Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

UIThread.h

Go to the documentation of this file.
00001 /*  UIThread.h - User interface wrappers (TODO::)
00002     Copyright (C) 2001-2004 Mark Weaver
00003     Written by Mark Weaver <mark@npsl.co.uk>
00004 
00005     Part of the Open-Win32 library.
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public
00017     License along with this library; if not, write to the
00018     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA  02111-1307, USA.
00020 */
00021 
00026 #ifndef OW32_UIThread_h
00027 #define OW32_UIThread_h
00028 
00029 #include <OW32/OW32Libs.h>
00030 #include <OW32/windows.h>
00031 #include <OW32/Thread.h>
00032 #include <tchar.h>
00033 
00034 namespace OW32
00035 {
00036 
00037 // eek: lifted from ATL oh well!
00038 #if defined(_M_IX86)
00039 #pragma pack(push,1)
00040 struct _WndProcThunk
00041 {
00042     DWORD   m_mov;          // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
00043     DWORD   m_this;         //
00044     BYTE    m_jmp;          // jmp WndProc
00045     DWORD   m_relproc;      // relative jmp
00046 };
00047 #pragma pack(pop)
00048 #endif
00049 
00050 extern DWORD g_TLSCreateWindowData; /* = TLS_OUT_OF_INDEXES; */
00051 
00052 class OW32_LIB_EXPORT CWindow;
00053 
00054 #ifdef _MSC_VER
00055 #pragma warning(disable: 4311 4312) // Doesn't work on Win64 anyway...
00056 class CWndProcThunk
00057 {
00058 public:
00059     _WndProcThunk thunk;
00060 
00061     CWindow* GetWindow() { return reinterpret_cast<CWindow*>(thunk.m_this); }
00062     WNDPROC GetWndProc() { return (WNDPROC)&thunk; }
00063 
00064     void Init(WNDPROC proc, void* pThis)
00065     {
00066         thunk.m_mov = 0x042444C7;  //C7 44 24 0C
00067         thunk.m_this = (DWORD)pThis;
00068         thunk.m_jmp = 0xe9;
00069         thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
00070         // write block from data cache and
00071         //  flush from instruction cache
00072         FlushInstructionCache(GetCurrentProcess(), &thunk, sizeof(thunk));
00073 
00074         if (g_TLSCreateWindowData == TLS_OUT_OF_INDEXES)
00075             g_TLSCreateWindowData = TlsAlloc();
00076 
00077         TlsSetValue(g_TLSCreateWindowData, this);
00078     }
00079 };
00080 #pragma warning(default: 4311 4312) // Doesn't work on Win64 anyway...
00081 #endif
00082 
00083 #define BEGIN_MESSAGE_MAP(BaseClass) \
00084     virtual LRESULT OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) \
00085     { \
00086         typedef BaseClass _BaseClass; \
00087         uMsg; wParam; lParam; bHandled = TRUE; \
00088 
00089 #define MESSAGE_HANDLER(msg, func) \
00090     if (uMsg == msg) { \
00091         return (func)(wParam, lParam); \
00092     }
00093 
00094 #define MESSAGE_HANDLER0(msg, func) \
00095     if (uMsg == msg) { \
00096         (func)(); \
00097         return 0L; \
00098     }
00099 
00100 #define MESSAGE_HANDLER1(msg, func) \
00101     if (uMsg == msg) { \
00102         (func)(wParam); \
00103         return 0L; \
00104     }
00105 
00106 #define MESSAGE_HANDLER2(msg, func) \
00107     if (uMsg == msg) { \
00108         (func)(lParam); \
00109         return 0L; \
00110     }
00111 
00112 #define MESSAGE_HANDLER3(msg, func) \
00113     if (uMsg == msg) { \
00114         return (func)(msg, wParam, lParam); \
00115     }
00116 
00117 #define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \
00118     if (uMsg >= msgFirst && uMsg <= msgLast) {  \
00119         LRESULT res = (func)(uMsg, wParam, lParam, bHandled); \
00120         if (bHandled) return res; \
00121     }
00122 
00123 #define COMMAND_ID_HANDLER0(id, func) \
00124     if (uMsg == WM_COMMAND && LOWORD(wParam) == id) { \
00125         (func)(); \
00126         return TRUE; \
00127     }
00128 
00129 #define COMMAND_CODE_ID_HANDLER0(code, id, func) \
00130     if (uMsg == WM_COMMAND && HIWORD(wParam) == code && LOWORD(wParam) == id) { \
00131         (func)(); \
00132         return TRUE; \
00133     }
00134 
00135 #define COMMAND_CODE_HANDLER(code, func) \
00136     if (uMsg == WM_COMMAND && HIWORD(wParam) == code) { \
00137         LRESULT res = (func)(id, HIWORD(wParam), (HWND)lParam, bHandled); \
00138         if (bHandled) return res; \
00139     }
00140 
00141 #define COMMAND_ID_HANDLER(id, func) \
00142     if (uMsg == WM_COMMAND && LOWORD(wParam) == id) { \
00143         LRESULT res = (func)(LOWORD(wParam), HIWORD(wParam), (HWND)lParam, bHandled); \
00144         if (bHandled) return res; \
00145     }
00146 
00147 #define COMMAND_HANDLER(func) \
00148     if (uMsg == WM_COMMAND) { \
00149         LRESULT res = (func)((int)LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam)); \
00150         return 0L; \
00151     }
00152 
00153 #define ON_SIZE() \
00154     if (uMsg == WM_SIZE) { \
00155         OnSize((int)LOWORD(lParam), (int)HIWORD(lParam), (UINT)wParam); \
00156         return 0L; \
00157     }
00158 
00159 #define ON_CREATE() \
00160     if (uMsg == WM_CREATE) { \
00161         return OnCreate((LPCREATESTRUCT)lParam) ? 0L : -1L; \
00162     }
00163 
00164 #define ON_LBUTTONUP() \
00165     if (uMsg == WM_LBUTTONUP) { \
00166         OnLButtonUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam); \
00167         return 0L; \
00168     }
00169 
00170 #define ON_LBUTTONDOWN() \
00171     if (uMsg == WM_LBUTTONDOWN) { \
00172         OnLButtonDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam); \
00173         return 0L; \
00174     }
00175 
00176 #define ON_RBUTTONUP() \
00177     if (uMsg == WM_LBUTTONUP) { \
00178         OnLButtonUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam); \
00179         return 0L; \
00180     }
00181 
00182 #define ON_RBUTTONDOWN() \
00183     if (uMsg == WM_LBUTTONDOWN) { \
00184         OnLButtonDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam); \
00185         return 0L; \
00186     }
00187 
00188 #define ON_MOUSEMOVE() \
00189     if (uMsg == WM_MOUSEMOVE) { \
00190         OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam); \
00191         return 0L; \
00192     }
00193 
00194 #define ON_PAINT() \
00195     if (uMsg == WM_PAINT) { \
00196         OnPaint(); \
00197         return 0L; \
00198     }
00199 
00200 #define ON_DESTROY() \
00201     if (uMsg == WM_DESTROY) { \
00202         OnDestroy(); \
00203         return 0L; \
00204     }
00205 
00206 #define END_MESSAGE_MAP() \
00207         LRESULT res = _BaseClass::OnMessage(uMsg, wParam, lParam, bHandled); \
00208         if (bHandled) return res; \
00209         bHandled = FALSE; \
00210         return 0; \
00211     }
00212 
00213 #define NOTIFY_HANDLER_CODE_ID0(ncode, id, func) \
00214     if (uMsg == WM_NOTIFY && (int)wParam == id && ((LPNMHDR)lParam)->code == ncode) { \
00215         (func)(); \
00216         return 0; \
00217     }
00218     
00219 #define DECLARE_EMPTY_MESSAGE_MAP() \
00220     virtual LRESULT OnMessage(UINT, WPARAM, LPARAM, BOOL& bHandled) { \
00221         bHandled = FALSE; \
00222         return 0; \
00223     }
00224 
00225 class OW32_LIB_EXPORT CWndClass : public WNDCLASS
00226 {
00227 public:
00228     ATOM m_Atom;
00229 
00230 /* TODO?:   ~CWndClass()
00231     {
00232         UnregisterWindowClass(
00233     }*/
00234 
00235     CWndClass()
00236     {
00237         ZeroMemory(this, sizeof(*this));
00238     }
00239 };
00240 
00241 class OW32_LIB_EXPORT CWndClassEx : public WNDCLASSEX
00242 {
00243 public:
00244     ATOM m_Atom;
00245 
00246     CWndClassEx()
00247     {
00248         ZeroMemory(this, sizeof(*this));
00249         cbSize = sizeof(WNDCLASSEX); 
00250     }
00251 };
00252 
00253 class OW32_LIB_EXPORT CWindow
00254 {
00255 protected:
00256     HWND m_hWnd;
00257     CWndProcThunk m_thunk;
00258 
00259 public:
00260     CWindow() :
00261         m_hWnd(NULL)
00262     {
00263         m_thunk.Init((WNDPROC)WndProc, this);
00264     }
00265 
00266     DECLARE_EMPTY_MESSAGE_MAP()
00267     virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
00268         return ::DefWindowProc(m_hWnd, message, wParam, lParam);
00269     }
00270     static LRESULT CALLBACK InitialWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
00271     static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
00272     static CWindow* CWindowFromHWND(HWND hWnd);
00273     
00274     virtual BOOL Create(LPCTSTR lpClassName, LPCTSTR lpWindowName = NULL, DWORD dwStyle = 0,
00275         int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, 
00276         int nWidth = CW_USEDEFAULT, int nHeight = CW_USEDEFAULT,
00277         HWND hWndParent = NULL, HMENU hMenu = NULL, HINSTANCE hInstance = NULL,
00278         LPVOID lpParam = NULL)
00279     {
00280         lpParam;
00281         m_hWnd = ::CreateWindow(lpClassName, lpWindowName, dwStyle, x, y, nWidth,
00282             nHeight, hWndParent, hMenu, hInstance, (LPVOID)this);
00283         return m_hWnd ? TRUE : FALSE;
00284     }
00285 
00286     BOOL Show(int nCmdShow)
00287     {
00288         return ::ShowWindow(m_hWnd, nCmdShow);
00289     }
00290 
00291     BOOL Update() { return UpdateWindow(m_hWnd); }
00292 
00293     static ATOM RegisterClass(LPCTSTR lpszClassName, HINSTANCE hInstance = NULL);
00294     static ATOM RegisterClass(CWndClass* pWndClass); // overrides WNDProc
00295     static ATOM RegisterClass(CWndClassEx* pWndClassEx); // overrides WNDProc
00296 
00297     operator HWND() const { return m_hWnd; }
00298 
00299     LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) {
00300         return ::SendMessage(m_hWnd, message, wParam, lParam);
00301     }
00302 
00303     LRESULT PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) {
00304         return ::PostMessage(m_hWnd, message, wParam, lParam);
00305     }
00306 
00307     static LRESULT SendMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
00308         return ::SendMessage(hWnd, message, wParam, lParam);
00309     }
00310 
00311     static LRESULT PostMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
00312         return ::PostMessage(hWnd, message, wParam, lParam);
00313     }
00314 
00315     int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT uMsg = MB_OK) {
00316         return ::MessageBox(m_hWnd, lpszText, lpszCaption, uMsg);
00317     }
00318 
00319     BOOL LockWindowUpdate() { return ::LockWindowUpdate(m_hWnd); }
00320     BOOL UnlockWindowUpdate() { return ::LockWindowUpdate(m_hWnd); }
00321     BOOL DestroyWindow() { return ::DestroyWindow(m_hWnd); }
00322 
00323     BOOL SetWindowText(LPCTSTR lpszText) { return ::SetWindowText(m_hWnd, lpszText); }
00324     int GetWindowText(LPTSTR lpszText, int nMaxCount) { return ::GetWindowText(m_hWnd, lpszText, nMaxCount); }
00325 
00326     HMENU GetMenu() { return ::GetMenu(m_hWnd); }
00327     BOOL SetMenu(HMENU hMenu) { return ::SetMenu(m_hWnd, hMenu); }
00328 
00329     BOOL GetClientRect(LPRECT lpRect) { return ::GetClientRect(m_hWnd, lpRect); }
00330     BOOL InvalidateRect(const RECT* lpRect, BOOL bErase) { return ::InvalidateRect(m_hWnd, lpRect, bErase); }
00331 
00332     HDC BeginPaint(LPPAINTSTRUCT lpPaint) { return ::BeginPaint(m_hWnd, lpPaint); }
00333     BOOL EndPaint(LPPAINTSTRUCT lpPaint) { return ::EndPaint(m_hWnd, lpPaint); }
00334 
00335     BOOL ClientToScreen(LPPOINT lpPoint) { return ::ClientToScreen(m_hWnd, lpPoint); }
00336     BOOL ScreenToClient(LPPOINT lpPoint) { return ::ScreenToClient(m_hWnd, lpPoint); }
00337 
00338     BOOL ClientToScreen(LPRECT lpRect) { 
00339         POINT pt1 = { lpRect->left, lpRect->top }, pt2 = { lpRect->right, lpRect->bottom };
00340         if (!(ClientToScreen(&pt1) && ClientToScreen(&pt2)))
00341             return FALSE;
00342         lpRect->left = pt1.x; lpRect->top = pt1.y;
00343         lpRect->right = pt2.x; lpRect->bottom = pt2.y;
00344         return TRUE;
00345     }
00346 
00347     BOOL ScreenToClient(LPRECT lpRect) { 
00348         POINT pt1 = { lpRect->left, lpRect->top }, pt2 = { lpRect->right, lpRect->bottom };
00349         if (!(ScreenToClient(&pt1) && ScreenToClient(&pt2)))
00350             return FALSE;
00351         lpRect->left = pt1.x; lpRect->top = pt1.y;
00352         lpRect->right = pt2.x; lpRect->bottom = pt2.y;
00353         return TRUE;
00354     }
00355 
00356     BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE) {
00357         return ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
00358     }
00359 
00360     BOOL MoveWindow(const RECT* lpRect, BOOL bRepaint = TRUE) {
00361         return MoveWindow(lpRect->left, lpRect->top, lpRect->right-lpRect->left+1, lpRect->bottom-lpRect->top+1, bRepaint);
00362     }
00363 
00364     BOOL SetWindowPos(int x, int y, int cx = 0, int cy = 0, HWND hwndInsertAfter = NULL, 
00365                       UINT uFlags = SWP_NOZORDER | SWP_NOSIZE)
00366     {
00367         return ::SetWindowPos(m_hWnd, hwndInsertAfter, x, y, cx, cy, uFlags);
00368     }
00369 
00370     // TODO: etc for SetWindowPos
00371 };
00372 
00373 class OW32_LIB_EXPORT CMDIChildWindow : public CWindow
00374 {
00375 public:
00376     virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
00377         return ::DefMDIChildProc(m_hWnd, message, wParam, lParam);
00378     }
00379 };
00380 
00381 class OW32_LIB_EXPORT CMDIFrameWindow : public CWindow
00382 {
00383 public:
00384     HWND m_hMDIClientWnd;
00385 
00386     CMDIFrameWindow() :
00387         m_hMDIClientWnd(NULL)
00388     {
00389     }
00390 
00391     void MDIActivate(HWND hWndChild) {
00392         (void)::SendMessage(m_hMDIClientWnd, WM_MDIACTIVATE, (WPARAM)hWndChild, (LPARAM)0L);
00393     }
00394 
00395     BOOL MDICascade(UINT uFlag = 0) {
00396         return (BOOL)::SendMessage(m_hMDIClientWnd, WM_MDICASCADE, (WPARAM)uFlag, (LPARAM)0L);
00397     }
00398 
00399     HWND MDIGetActive(LPBOOL lpMaximisedState = NULL) {
00400         return (HWND)::SendMessage(m_hMDIClientWnd, WM_MDIGETACTIVE, (WPARAM)0, (LPARAM)lpMaximisedState);
00401     }
00402 
00403     void MDIIconArrange() {
00404         (void)::SendMessage(m_hMDIClientWnd, WM_MDIICONARRANGE, (WPARAM)0, (LPARAM)0L);
00405     }
00406 
00407     void MDIMaximize(HWND hWndChild) {
00408         (void)::SendMessage(m_hMDIClientWnd, WM_MDIMAXIMIZE, (WPARAM)hWndChild, (LPARAM)0L);
00409     }
00410 
00411     void MDINext(HWND hWndChild = NULL) {
00412         (void)::SendMessage(m_hMDIClientWnd, WM_MDINEXT, (WPARAM)hWndChild, (LPARAM)0);
00413     }
00414 
00415     void MDIPrev(HWND hWndChild = NULL) {
00416         (void)::SendMessage(m_hMDIClientWnd, WM_MDINEXT, (WPARAM)hWndChild, (LPARAM)1);
00417     }
00418 
00419     HMENU MDIRefreshMenu() {
00420         return (HMENU)::SendMessage(m_hMDIClientWnd, WM_MDIREFRESHMENU, (WPARAM)0, (LPARAM)0L);
00421     }
00422 
00423     void MDIRestore(HWND hWndChild) {
00424         (void)::SendMessage(m_hMDIClientWnd, WM_MDIRESTORE, (WPARAM)hWndChild, (LPARAM)0L);
00425     }
00426 
00427     HMENU MDISetMenu(HMENU hMenuFrame = NULL, HMENU hMenuWindow = NULL) {
00428         return (HMENU)::SendMessage(m_hMDIClientWnd, WM_MDISETMENU, (WPARAM)hMenuFrame, (LPARAM)hMenuWindow);
00429     }
00430 
00431 
00432     BOOL MDITile(UINT uFlag = MDITILE_VERTICAL) {
00433         return (BOOL)::SendMessage(m_hMDIClientWnd, WM_MDITILE, (WPARAM)uFlag, (LPARAM)0L);
00434     }
00435 
00436     virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
00437         if (m_hMDIClientWnd)
00438             return ::DefFrameProc(m_hWnd, m_hMDIClientWnd, message, wParam, lParam);
00439         else
00440             return ::DefWindowProc(m_hWnd, message, wParam, lParam);
00441     }
00442 };
00443 
00444 class OW32_LIB_EXPORT CUIThread : public CThread
00445 {
00446 public:
00447     CUIThread(bool bAutoDelete=false) :
00448       CThread(bAutoDelete) {}
00449 
00450     // Overrides of CThread that implement base UI functionality
00451     virtual unsigned Run(); 
00452 };
00453 
00454 } // namespace OW32
00455 
00456 #endif // OW32_UIThread_h

Generated on Sun Jun 5 01:29:18 2005 for OW32 by  doxygen 1.3.9.1