19#if defined(__i386__) || defined(__X86__) || defined(_M_IX86)
27 void Init(DWORD_PTR proc,
void *pThis)
30 m_this = (DWORD)(ULONG_PTR)pThis;
32 m_relproc = (DWORD)((INT_PTR)proc - ((INT_PTR)
this +
sizeof(tagThunk)));
33 FlushInstructionCache(GetCurrentProcess(),
this,
sizeof(tagThunk));
35 void *GetCodeAddress()
41#elif defined(_M_AMD64) || defined(__amd64__) || defined(__x86_64__)
51 void Init(DWORD_PTR proc,
void *pThis)
54 RdiImm = (ULONG64)pThis;
56 RaxImm = (ULONG64)proc;
58 BOOL b = FlushInstructionCache(GetCurrentProcess(),
this,
sizeof(tagThunk));
61 void *GetCodeAddress()
75 void Init(DWORD_PTR proc,
void *pThis)
78 RcxImm = (ULONG64)pThis;
80 RaxImm = (ULONG64)proc;
82 FlushInstructionCache(GetCurrentProcess(),
this,
sizeof(tagThunk));
85 void *GetCodeAddress()
93#elif defined(__arm__) || defined(_M_ARM)
101 void Init(DWORD_PTR proc,
void *pThis)
103 m_mov_r0 = 0xE59F0000;
104 m_mov_pc = 0xE59FF000;
105 m_pThis = (DWORD)pThis;
106 m_pFunc = (DWORD)proc;
109 FlushInstructionCache(GetCurrentProcess(),
this,
sizeof(tagThunk));
111 void *GetCodeAddress()
117#elif defined(__arm64__) || defined(_M_ARM64) || defined(__aarch64__)
128 void Init(DWORD_PTR proc,
void *pThis)
130 m_ldr_r16 = 0x580000D0;
131 m_ldr_r0 = 0x58000060;
133 m_pThis = (ULONG64)pThis;
134 m_pFunc = (ULONG64)proc;
137 FlushInstructionCache(GetCurrentProcess(),
this,
sizeof(tagThunk));
139 void *GetCodeAddress()
146#error Only AMD64, ARM, ARM64 and X86 supported
149SNativeWndHelper::SNativeWndHelper()
162 m_hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
167SNativeWndHelper::~SNativeWndHelper()
170 HeapDestroy(m_hHeap);
172 UnregisterClass((LPCTSTR)(UINT_PTR)m_atom, m_hInst);
187SNativeWnd::SNativeWnd()
188 : m_bDestoryed(FALSE)
189 , m_pCurrentMsg(NULL)
191 , m_pfnSuperWindowProc(::DefWindowProc)
194 m_msgHandlerInfo.fun = NULL;
195 m_msgHandlerInfo.ctx = NULL;
198SNativeWnd::~SNativeWnd(
void)
204 WNDCLASSEX wcex = {
sizeof(WNDCLASSEX), 0 };
205 wcex.cbSize =
sizeof(WNDCLASSEX);
206 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | (bImeWnd ? CS_IME : 0);
208 wcex.hInstance = hInst;
209 wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW);
210 wcex.lpszClassName = pszSimpleWndName;
211 return ::RegisterClassEx(&wcex);
219HWND
SNativeWnd::CreateNative(LPCTSTR lpWindowName, DWORD dwStyle, DWORD dwExStyle,
int x,
int y,
int nWidth,
int nHeight, HWND hWndParent,
int nID, LPVOID lpParam)
225 HWND hWnd = ::CreateWindowEx(dwExStyle, (LPCTSTR)(UINT_PTR)
SNativeWndHelper::instance()->GetSimpleWndAtom(), lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, (HMENU)(UINT_PTR)nID,
SNativeWndHelper::instance()->GetAppInstance(), lpParam);
257 SNativeWnd *pThis = (SNativeWnd *)hWnd;
261 MSG msg = { pThis->
m_hWnd, uMsg, wParam, lParam };
280 if (uMsg != WM_NCDESTROY)
296 HWND hWndThis = pThis->
m_hWnd;
319 WNDPROC pProc = (WNDPROC)pThis->
m_pThunk->GetCodeAddress();
322 return pProc(hWnd, uMsg, wParam, lParam);
326 return WindowProc(hWnd, uMsg, wParam, lParam);
337 WNDPROC pProc = (WNDPROC)
m_pThunk->GetCodeAddress();
342 WNDPROC pfnWndProc = (WNDPROC)
::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc);
343 if (pfnWndProc == NULL)
361 WNDPROC pOurProc = (WNDPROC)
m_pThunk->GetCodeAddress();
368 if (bForce || pOurProc == pActiveProc)
389 case WM_PARENTNOTIFY:
416 hWndChild = (HWND)lParam;
419 hWndChild = ((LPNMHDR)lParam)->hwndFrom;
421 case WM_PARENTNOTIFY:
422 switch (LOWORD(wParam))
426 hWndChild = (HWND)lParam;
429 hWndChild = GetDlgItem(
m_hWnd, HIWORD(wParam));
435 hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
439 hWndChild = GetDlgItem(
m_hWnd, ((LPMEASUREITEMSTRUCT)lParam)->CtlID);
443 hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem;
447 hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem;
454 hWndChild = (HWND)lParam;
459 case WM_CTLCOLOREDIT:
460 case WM_CTLCOLORLISTBOX:
461 case WM_CTLCOLORMSGBOX:
462 case WM_CTLCOLORSCROLLBAR:
463 case WM_CTLCOLORSTATIC:
464 hWndChild = (HWND)lParam;
478 return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
487 case OCM_PARENTNOTIFY:
489 case OCM_MEASUREITEM:
490 case OCM_COMPAREITEM:
497 case OCM_CTLCOLORBTN:
498 case OCM_CTLCOLORDLG:
499 case OCM_CTLCOLOREDIT:
500 case OCM_CTLCOLORLISTBOX:
501 case OCM_CTLCOLORMSGBOX:
502 case OCM_CTLCOLORSCROLLBAR:
503 case OCM_CTLCOLORSTATIC:
523 lRes =
DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
535 if (dwStyle & WS_CHILD)
538 hWndCenter = ::GetWindow(
m_hWnd, GW_OWNER);
542 hWndCenter = ::GetActiveWindow();
554 if (!(dwStyle & WS_CHILD))
560 if (!(dwStyleCenter & WS_VISIBLE) || (dwStyleCenter & WS_MINIMIZE))
566 ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
568 HMONITOR hMonitor = 0;
571 hMonitor = ::MonitorFromWindow(hWndCenter, MONITOR_DEFAULTTONEAREST);
575 hMonitor = ::MonitorFromWindow(
m_hWnd, MONITOR_DEFAULTTONEAREST);
579 minfo.cbSize =
sizeof(MONITORINFO);
580 ::GetMonitorInfo(hMonitor, &minfo);
582 rcArea = minfo.rcWork;
587 ::GetWindowRect(hWndCenter, &rcCenter);
601 int DlgWidth = rcDlg.right - rcDlg.left;
602 int DlgHeight = rcDlg.bottom - rcDlg.top;
605 int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2;
606 int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2;
609 if (xLeft + DlgWidth > rcArea.right)
610 xLeft = rcArea.right - DlgWidth;
611 if (xLeft < rcArea.left)
614 if (yTop + DlgHeight > rcArea.bottom)
615 yTop = rcArea.bottom - DlgHeight;
616 if (yTop < rcArea.top)
620 return ::SetWindowPos(
m_hWnd, 0, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
628 DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
629 if (dwStyle == dwNewStyle)
635 ::SetWindowPos(
m_hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
647 DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
648 if (dwStyle == dwNewStyle)
654 ::SetWindowPos(
m_hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
669 return ::UpdateLayeredWindow(
m_hWnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crKey, pblend, dwFlags);
678 return ::SetLayeredWindowAttributes(
m_hWnd, crKey, bAlpha, dwFlags);
684 return ::SetWindowRgn(
m_hWnd, hRgn, bRedraw);
690 return ::ShowWindow(
m_hWnd, nCmdShow);
696 return ::MoveWindow(
m_hWnd, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, bRepaint);
702 return ::MoveWindow(
m_hWnd, x, y, nWidth, nHeight, bRepaint);
708 return ::IsWindowVisible(
m_hWnd);
714 return ::IsZoomed(
m_hWnd);
720 return ::IsIconic(
m_hWnd);
726 return ::GetWindowText(
m_hWnd, lpszStringBuf, nMaxCount);
732 return ::SetWindowText(
m_hWnd, lpszString);
738 return ::SendNotifyMessage(
m_hWnd, message, wParam, lParam);
744 return ::PostMessage(
m_hWnd, message, wParam, lParam);
750 return ::SendMessage(
m_hWnd, message, wParam, lParam);
756 return ::SetFocus(
m_hWnd);
762 return ::SetCapture(
m_hWnd);
767 return ::GetCapture();
772 return ::ReleaseCapture();
778 return ::ShowCaret(
m_hWnd);
784 return ::HideCaret(
m_hWnd);
790 return ::CreateCaret(
m_hWnd, hBitmap, nWidth, nHeight);
796 return ::ReleaseDC(
m_hWnd, hDC);
802 return ::GetWindowDC(
m_hWnd);
814 return ::KillTimer(
m_hWnd, nIDEvent);
817UINT_PTR
SNativeWnd::SetTimer(UINT_PTR nIDEvent, UINT nElapse,
void(CALLBACK *lpfnTimer)(HWND, UINT, UINT_PTR, DWORD) )
820 return ::SetTimer(
m_hWnd, nIDEvent, nElapse, (TIMERPROC)lpfnTimer);
826 return ::MapWindowPoints(
m_hWnd, hWndTo, (LPPOINT)lpRect, 2);
832 return ::MapWindowPoints(
m_hWnd, hWndTo, lpPoint, nCount);
840 return ::ScreenToClient(
m_hWnd, ((LPPOINT)lpRect) + 1);
846 return ::ScreenToClient(
m_hWnd, lpPoint);
854 return ::ClientToScreen(
m_hWnd, ((LPPOINT)lpRect) + 1);
860 return ::ClientToScreen(
m_hWnd, lpPoint);
866 return ::GetClientRect(
m_hWnd, lpRect);
872 return ::GetWindowRect(
m_hWnd, lpRect);
878 return ::InvalidateRect(
m_hWnd, lpRect, bErase);
884 return ::InvalidateRect(
m_hWnd, NULL, bErase);
889 return ::IsWindow(
m_hWnd);
895 return ::DestroyWindow(
m_hWnd);
901 return ::SetWindowPos(
m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags);
907 return ::IsWindowEnabled(
m_hWnd);
913 return ::SetParent(
m_hWnd, hWndNewParent);
919 return ::GetParent(
m_hWnd);
925 return ::SetWindowLongPtr(
m_hWnd, nIndex, dwNewLong);
931 return ::GetWindowLongPtr(
m_hWnd, nIndex);
949 return ::GetDlgCtrlID(
m_hWnd);
Header file for SCriticalSection and SAutoLock classes.
Interface and Implementation for Native Window Handling.
Auto-lock class for managing critical sections.
static SNativeWndHelper * instance()
Retrieves the singleton instance of SNativeWndHelper.
void UnlockSharePtr()
Unlocks a shared pointer.
BOOL Init(HINSTANCE hInst, LPCTSTR pszClassName, BOOL bImeApp)
Initializes the helper with the application instance and window class name.
void LockSharePtr(void *p)
Locks a shared pointer.
BOOL IsIconic() SCONST OVERRIDE
Checks if the window is iconic (minimized).
BOOL IsZoomed() SCONST OVERRIDE
Checks if the window is zoomed (maximized).
BOOL ClientToScreen2(LPRECT lpRect) SCONST OVERRIDE
Converts client rectangle coordinates to screen coordinates.
BOOL ScreenToClient(LPPOINT lpPoint) SCONST OVERRIDE
Converts screen coordinates to client coordinates.
static void InitWndClass(HINSTANCE hInst, LPCTSTR pszSimpleWndName, BOOL bImeWnd)
Initializes the window class.
int SetWindowRgn(HRGN hRgn, BOOL bRedraw=TRUE) OVERRIDE
Sets the window region.
int MapWindowRect(HWND hWndTo, LPRECT lpRect) SCONST OVERRIDE
Maps a rectangle from one window to another.
HDC GetDC() OVERRIDE
Retrieves a device context for the window.
const MSG * m_pCurrentMsg
Pointer to the current message.
HWND SetCapture() OVERRIDE
Sets the window to capture the mouse.
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Window procedure callback function.
BOOL GetWindowRect(LPRECT lpRect) SCONST OVERRIDE
Retrieves the window rectangle.
LRESULT ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Reflects notifications to the appropriate handler.
HWND GetCapture() OVERRIDE
Retrieves the handle to the window that has captured the mouse.
BOOL ReleaseCapture() OVERRIDE
Releases the mouse capture.
int MapWindowPoints(HWND hWndTo, LPPOINT lpPoint, UINT nCount) SCONST OVERRIDE
Maps points from one window to another.
BOOL SetLayeredWindowAttributes(COLORREF crKey, BYTE bAlpha, DWORD dwFlags) OVERRIDE
Sets the layered window attributes.
BOOL IsWindowVisible() SCONST OVERRIDE
Checks if the window is visible.
BOOL Invalidate(BOOL bErase=TRUE) OVERRIDE
Invalidates the entire window.
BOOL IsWindow() SCONST OVERRIDE
Checks if the handle is a valid window handle.
BOOL IsWindowEnabled() SCONST OVERRIDE
Checks if the window is enabled.
LRESULT SendMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0) OVERRIDE
Sends a message to the window.
const MSG * GetCurrentMessage() SCONST OVERRIDE
Retrieves the current message being processed.
void SetMsgHandler(FunMsgHandler fun, void *ctx) OVERRIDE
Sets the message handler for the window.
BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint=TRUE) OVERRIDE
Moves the window to the specified position and resizes it.
tagThunk * m_pThunk
Thunk structure.
BOOL SendNotifyMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0) OVERRIDE
Sends a notify message to the window.
LRESULT ForwardNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Forwards notifications to the appropriate handler.
WNDPROC m_pfnSuperWindowProc
Pointer to the superclass window procedure.
UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void(CALLBACK *lpfnTimer)(HWND, UINT, UINT_PTR, DWORD)=NULL) OVERRIDE
Sets a timer for the window.
HWND UnsubclassWindow(BOOL bForce=FALSE) OVERRIDE
Unsubclasses a window.
BOOL ShowCaret() OVERRIDE
Shows the caret.
MsgHandlerInfo m_msgHandlerInfo
Message handler information.
static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Start window procedure callback function (executed once).
BOOL SubclassWindow(HWND hWnd) OVERRIDE
Subclasses an existing window.
BOOL PostMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0) OVERRIDE
Posts a message to the window.
DWORD GetStyle() SCONST OVERRIDE
Retrieves the window style.
HWND GetParent() OVERRIDE
Retrieves the handle to the parent window.
HWND SetFocus() OVERRIDE
Sets the input focus to the window.
DWORD GetExStyle() SCONST OVERRIDE
Retrieves the extended window style.
virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID=0)
Processes a window message.
HWND SetParent(HWND hWndNewParent) OVERRIDE
Sets the handle to the parent window.
BOOL SetWindowText(LPCTSTR lpszString) OVERRIDE
Sets the window text.
BOOL m_bDestoryed
Flag indicating if the window is destroyed.
BOOL ClientToScreen(LPPOINT lpPoint) SCONST OVERRIDE
Converts client coordinates to screen coordinates.
static ATOM RegisterSimpleWnd(HINSTANCE hInst, LPCTSTR pszSimpleWndName, BOOL bImeWnd)
Registers a simple window class.
BOOL ShowWindow(int nCmdShow) OVERRIDE
Sets the show state of the window.
BOOL KillTimer(UINT_PTR nIDEvent) OVERRIDE
Kills a timer for the window.
HWND m_hWnd
Handle to the window.
int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount) SCONST OVERRIDE
Retrieves the window text.
BOOL CreateCaret(HBITMAP hBitmap, int nWidth, int nHeight) OVERRIDE
Creates a caret for the window.
LONG_PTR SetWindowLongPtr(int nIndex, LONG_PTR dwNewLong) OVERRIDE
Sets the long pointer value at the specified index.
BOOL CenterWindow(HWND hWndCenter=0) OVERRIDE
Centers the window relative to another window.
BOOL GetClientRect(LPRECT lpRect) SCONST OVERRIDE
Retrieves the client rectangle.
BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags=0) OVERRIDE
Modifies the window style.
HDC GetWindowDC() OVERRIDE
Retrieves a device context for the entire window.
HWND CreateNative(LPCTSTR lpWindowName, DWORD dwStyle, DWORD dwExStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, int nID=0, LPVOID lpParam=0) OVERRIDE
Creates a native window.
static BOOL DefaultReflectionHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
Default reflection handler for notifications.
BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags=0) OVERRIDE
Modifies the extended window style.
BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags) OVERRIDE
Sets the window position.
HWND GetHwnd() OVERRIDE
Retrieves the handle to the window.
virtual void OnFinalMessage(HWND hWnd)
Handles the final message for the window.
int ReleaseDC(HDC hDC) OVERRIDE
Releases a device context.
BOOL HideCaret() OVERRIDE
Hides the caret.
BOOL ScreenToClient2(LPRECT lpRect) SCONST OVERRIDE
Converts screen rectangle coordinates to client coordinates.
int GetDlgCtrlID() SCONST OVERRIDE
Retrieves the dialog control ID.
MsgHandlerInfo * GetMsgHandler() OVERRIDE
Retrieves the message handler for the window.
LONG_PTR GetWindowLongPtr(int nIndex) SCONST OVERRIDE
Retrieves the long pointer value at the specified index.
BOOL UpdateLayeredWindow(HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags) OVERRIDE
Updates the layered window.
LRESULT DefWindowProc()
Calls the default window procedure.
BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase=TRUE) OVERRIDE
Invalidates a specified rectangle of the window.
BOOL DestroyWindow() OVERRIDE
Destroys the window.
BOOL MoveWindow2(LPCRECT lpRect, BOOL bRepaint=TRUE) OVERRIDE
Moves the window to the specified position and resizes it using a rectangle.
Structure containing message handler information.