00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00038 #if defined(_M_IX86)
00039 #pragma pack(push,1)
00040 struct _WndProcThunk
00041 {
00042 DWORD m_mov;
00043 DWORD m_this;
00044 BYTE m_jmp;
00045 DWORD m_relproc;
00046 };
00047 #pragma pack(pop)
00048 #endif
00049
00050 extern DWORD g_TLSCreateWindowData;
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;
00067 thunk.m_this = (DWORD)pThis;
00068 thunk.m_jmp = 0xe9;
00069 thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
00070
00071
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
00231
00232
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);
00295 static ATOM RegisterClass(CWndClassEx* pWndClassEx);
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
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
00451 virtual unsigned Run();
00452 };
00453
00454 }
00455
00456 #endif // OW32_UIThread_h