NtUserMessageCall 내부에서의 메세지 처리
함수원형
__declspec(naked) LRESULT __stdcall NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR xParam, DWORD xpfnProc, BOOL bAnsi ) |
NtUserMessageCall 은… SendMessage 에 해당하는 시스템 서비스던가…? 기억력 감퇴;;
어찌되었든, NtUserMessageCall 에서의 메시지 처리는 xpfnProc 인자를 통해 이뤄집니다.
해당 인자는 Message를 처리해야 하는 win32k 의 처리 procedure 를 가리킵니다.
확인을 해보면,
가령 NtUserMessageCall 을 호출하는 RealDefWindowProcWorker 의 경우
.text:77D7AEB2 loc_77D7AEB2: ; CODE XREF: RealDefWindowProcWorker(x,x,x,x,x)-81C1j .text:77D7AEB2 ; RealDefWindowProcWorker(x,x,x,x,x)+B2C9j ... .text:77D7AEB2 push [ebp+lpMultiByteStr] .text:77D7AEB5 push 2B0h // FNID_SENDMESSAGEEX .text:77D7AEBA push 0 .text:77D7AEBC push 0 .text:77D7AEBE push [ebp+hMem] .text:77D7AEC1 push 128h .text:77D7AEC6 .text:77D7AEC6 loc_77D7AEC6: ; CODE XREF: RealDefWindowProcWorker(x,x,x,x,x)-81CAj .text:77D7AEC6 ; RealDefWindowProcWorker(x,x,x,x,x)+3029Fj .text:77D7AEC6 push ebx .text:77D7AEC7 jmp loc_77D4C756 .text:77D4C756 loc_77D4C756: ; CODE XREF: RealDefWindowProcWorker(x,x,x,x,x)+2FE07j .text:77D4C756 call ds:_gapfnScSendMessage ; NtUserMessageCall(x,x,x,x,x,x,x) |
xpfnProc 에 0x2B0h 값
.text:77D4B2A5 loc_77D4B2A5: ; CODE XREF: RealDefWindowProcWorker(x,x,x,x,x)+38j .text:77D4B2A5 cmp edi, 400h .text:77D4B2AB push [ebp+lpMultiByteStr] ; int .text:77D4B2AE push 29Eh // FNID_DEFWINDOWPROC .text:77D4B2B3 push 0 ; int .text:77D4B2B5 push [ebp+hMem] ; hMem .text:77D4B2B8 push dword ptr [ebp+WideCharStr] ; int .text:77D4B2BB push edi ; int .text:77D4B2BC push eax ; int .text:77D4B2BD jnb loc_77D7AB10 .text:77D4B2C3 xor ecx, ecx .text:77D4B2C5 mov cl, ds:_MessageTable[edi] .text:77D4B2CB and ecx, 3Fh ; int .text:77D4B2CE call ds:_gapfnScSendMessage[ecx*4] ; NtUserMessageCall(x,x,x,x,x,x,x) |
xpfnProc 에 0x29Eh 값
위의 두 부분에서 NtUserMessageCall 을 호출하고 있으며,
이때, NtUserMessageCall 에서는 이를 다음과 같이 처리합니다.
bf834b50 8b4d1c mov ecx,dword ptr [ebp+1Ch] // xpfnProc bf834b53 83c106 add ecx,6 bf834b56 83e11f and ecx,1Fh bf834b59 ff7518 push dword ptr [ebp+18h] bf834b5c 50 push eax bf834b5d ff7510 push dword ptr [ebp+10h] bf834b60 ff750c push dword ptr [ebp+0Ch] bf834b63 ff7508 push dword ptr [ebp+8] bf834b66 a158859abf mov eax,dword ptr [win32k!gpsi (bf9a8558)] bf834b6b ff54880c call dword ptr [eax+ecx*4+0Ch] |
위의 어셈 코드에서, 호출되는 procedure 의 주소를 보면,
bc5d0650 00200031 bc5d0654 00000000 bc5d0658 00000155 bc5d065c bf90ade2 win32k!xxxWrapSBWnd16Proc bc5d0660 bf80f420 win32k!xxxWrapRealDefWindowProc bc5d0664 bf86a712 win32k!xxxWrapMenuWindowProc bc5d0668 bf915448 win32k!xxxWrapDesktopWndProc bc5d066c bf80f420 win32k!xxxWrapRealDefWindowProc >> (29E+6) & 1F bc5d0670 bf80f420 win32k!xxxWrapRealDefWindowProc bc5d0674 bf8cb6f2 win32k!xxxWrapSwitchWndProc bc5d0678 bf942a7c win32k!xxxUnusedFunctionId bc5d067c bf942a7c win32k!xxxUnusedFunctionId bc5d0680 bf942a7c win32k!xxxUnusedFunctionId bc5d0684 bf942a7c win32k!xxxUnusedFunctionId bc5d0688 bf942a7c win32k!xxxUnusedFunctionId bc5d068c bf942a7c win32k!xxxUnusedFunctionId bc5d0690 bf942a7c win32k!xxxUnusedFunctionId bc5d0694 bf942a7c win32k!xxxUnusedFunctionId bc5d0698 bf942a7c win32k!xxxUnusedFunctionId bc5d069c bf90b699 win32k!fnHkINLPCWPEXSTRUCT bc5d06a0 bf92f155 win32k!fnHkINLPCWPRETEXSTRUCT bc5d06a4 bf942a7c win32k!xxxUnusedFunctionId bc5d06a8 bf942a7c win32k!xxxUnusedFunctionId bc5d06ac bf942a7c win32k!xxxUnusedFunctionId bc5d06b0 bf942a7c win32k!xxxUnusedFunctionId bc5d06b4 bf831785 win32k!xxxWrapSendMessage >> (2B0+6) & 1F bc5d06b8 bf8a003f win32k!xxxSendMessageFF bc5d06bc bf82eedc win32k!xxxSendMessageEx bc5d06c0 bf89ef23 win32k!xxxWrapCallWindowProc bc5d06c4 bf8622d9 win32k!xxxWrapSendMessageBSM bc5d06c8 bf942a7c win32k!xxxUnusedFunctionId bc5d06cc bf942a7c win32k!xxxUnusedFunctionId bc5d06d0 bf82f3dd win32k!xxxWrapSendNotifyMessage bc5d06d4 bf82f461 win32k!xxxWrapSendMessageCallback bc5d06d8 bf942a7c win32k!xxxUnusedFunctionId bc5d06dc bf90a41b win32k!xxxSBWndProc bc5d06e0 bf80d027 win32k!xxxDefWindowProc bc5d06e4 bf865f56 win32k!xxxMenuWindowProc bc5d06e8 bf87fac4 win32k!xxxDesktopWndProc bc5d06ec bf80d027 win32k!xxxDefWindowProc bc5d06f0 bf80d027 win32k!xxxDefWindowProc |
위와 같이 메시지를 처리하는 실제 procedure 들의 주소가 담긴 테이블을 확인할 수 있으며,
RealDefWindowProcWorker 가 호출하는 0x2B0, 0x29E 인자에 대응하는 실제 procedure 를 찾을 수 있습니다.
다음은 xpfnProc에 대응하는 FNID 값입니다.
#define FNID_START 0x0000029A #define FNID_WNDPROCSTART 0x0000029A #define FNID_SCROLLBAR 0x0000029A // xxxSBWndProc; #define FNID_ICONTITLE 0x0000029B // xxxDefWindowProc; #define FNID_MENU 0x0000029C // xxxMenuWindowProc; #define FNID_DESKTOP 0x0000029D // xxxDesktopWndProc; #define FNID_DEFWINDOWPROC 0x0000029E // xxxDefWindowProc; #define FNID_WNDPROCEND 0x0000029E // see PatchThreadWindows #define FNID_CONTROLSTART 0x0000029F #define FNID_BUTTON 0x0000029F // No server side proc #define FNID_COMBOBOX 0x000002A0 // No server side proc #define FNID_COMBOLISTBOX 0x000002A1 // No server side proc #define FNID_DIALOG 0x000002A2 // No server side proc #define FNID_EDIT 0x000002A3 // No server side proc #define FNID_LISTBOX 0x000002A4 // No server side proc #define FNID_MDICLIENT 0x000002A5 // No server side proc #define FNID_STATIC 0x000002A6 // No server side proc #define FNID_IME 0x000002A7 // No server side proc #define FNID_CONTROLEND 0x000002A7 #define FNID_HKINLPCWPEXSTRUCT 0x000002A8 #define FNID_HKINLPCWPRETEXSTRUCT 0x000002A9 #define FNID_DEFFRAMEPROC 0x000002AA // No server side proc #define FNID_DEFMDICHILDPROC 0x000002AB // No server side proc #define FNID_MB_DLGPROC 0x000002AC // No server side proc #define FNID_MDIACTIVATEDLGPROC 0x000002AD // No server side proc #define FNID_SENDMESSAGE 0x000002AE #define FNID_SENDMESSAGEFF 0x000002AF #define FNID_SENDMESSAGEEX 0x000002B0 #define FNID_CALLWINDOWPROC 0x000002B1 #define FNID_SENDMESSAGEBSM 0x000002B2 #define FNID_SWITCH 0x000002B3 // Just used by GetTopMostInserAfter #define FNID_TOOLTIP 0x000002B4 #define FNID_END 0x000002B4 |
Windows Controls ( User Interface )
Windows Controls
A control is a child window that an application uses in conjunction with another window to enable user interaction. Controls are most often used within dialog boxes, but they can also be used in other windows. Controls within dialog boxes provide the user with a way to type text, choose options, and initiate actions. Controls in other windows provide a variety of services, such as letting the user choose commands, view status, and view and edit text.
The common controls overview documentation describes the common controls delivered in Microsoft Windows and the programming elements used to create and manipulate them.
The following table lists the Windows controls.
Control |
Description |
A window that displays an Audio-Video Interleaved (AVI) clip. | |
Notifies the parent window when the user selects the control. | |
A combination of a list box and an edit control, enabling the user to select or add items. | |
An extension of the combo box control that provides native support for item images. | |
A simple and intuitive interface through which to exchange date and time information with a user. | |
A type of list box that enables the user to drag items from one position to another. | |
A window within the user can view and edit text. | |
A scroll bar with a more customizable appearance than standard scroll bars. | |
A window that is usually positioned above columns of text or numbers. It contains a title for each column, and it can be divided into parts. | |
A window that enables the user to enter a combination of keystrokes to be used as a hot key. | |
A collection of images of the same size, each of which can be referred to by its index. | |
A window in which the user can enter an Internet Protocol (IP) address in an easily understood format. | |
A simple list from which the user can select one or more items. | |
A list box that provides several ways to arrange and display the items. | |
A calendar that enables the user to select a date or dates. | |
A set of arrow buttons that enable the contents of a control window to be scrolled. | |
An animated control that indicates the progress of a lengthy operation. | |
A dialog box that enables the user to view and edit the properties of an item. Pages may be viewed as tabs, or in succession as a wizard. | |
A container for child windows. An application assigns child windows, which are often other controls, to a rebar control band. | |
A window in which the user can view and edit text with character and paragraph formatting. It can also contain embedded COM objects. | |
A control that enables the user to choose the direction and distance to scroll information in a related window. | |
Non-interactive text, including labels for other controls. | |
A horizontal window at the bottom of a parent window in which an application can display various kinds of status information. | |
A hypertext link. | |
A selectable page, analogous to a divider in a notebook. By using a tab control, an application can define multiple pages for the same area of a window or dialog box. | |
A more powerful alternative to simple message boxes, incorporating elements such as custom buttons, radio buttons, hyperlinks, and progress bars. | |
A window that contains one or more buttons and possibly other controls. | |
A message that appears automatically when the mouse pointer hovers over a tool. | |
A slider with optional tick marks, used to set a value within a range. | |
A hierarchical list of items, such as the headings in a document or the files and directories on a disk. | |
A pair of arrow buttons that the user can click to increment or decrement a value, such as a scroll position or a number displayed in a companion control. |
Windows Message Notifications
WM_ACTIVATEAPP
The WM_ACTIVATEAPP message is sent when a window belonging to a different application than the active window is about to be activated. The message is sent to the application whose window is being activated and to the application whose window is being deactivated.
A window receives this message through its WindowProc function.
WM_CANCELMODEThe WM_CANCELMODE message is sent to cancel certain modes, such as mouse capture. For example, the system sends this message to the active window when a dialog box or message box is displayed. Certain functions also send this message explicitly to the specified window regardless of whether it is the active window. For example, the EnableWindow function sends this message when disabling the specified window.
A window receives this message through its WindowProc function.
WM_CHILDACTIVATEThe WM_CHILDACTIVATE message is sent to a child window when the user clicks the window's title bar or when the window is activated, moved, or sized.
A window receives this message through its WindowProc function.
WM_CLOSEThe WM_CLOSE message is sent as a signal that a window or an application should terminate.
A window receives this message through its WindowProc function.
WM_COMPACTINGThe WM_COMPACTING message is sent to all top-level windows when the system detects more than 12.5 percent of system time over a 30- to 60-second interval is being spent compacting memory. This indicates that system memory is low.
A window receives this message through its WindowProc function.
WM_CREATE
The WM_CREATE message is sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function. (The message is sent before the function returns.) The window procedure of the new window receives this message after the window is created, but before the window becomes visible.
A window receives this message through its WindowProc function.
WM_DESTROYThe WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen.
This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist.
A window receives this message through its WindowProc function.
WM_ENABLEThe WM_ENABLE message is sent when an application changes the enabled state of a window. It is sent to the window whose enabled state is changing. This message is sent before the EnableWindow function returns, but after the enabled state (WS_DISABLED style bit) of the window has changed.
A window receives this message through its WindowProc function.
WM_ENTERSIZEMOVEThe WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving or sizing modal loop. The window enters the moving or sizing modal loop when the user clicks the window's title bar or sizing border, or when the window passes the WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the message specifies the SC_MOVE
or SC_SIZE
value. The operation is complete when DefWindowProc returns.
The system sends the WM_ENTERSIZEMOVE message regardless of whether the dragging of full windows is enabled.
A window receives this message through its WindowProc function.
WM_EXITSIZEMOVEThe WM_EXITSIZEMOVE message is sent one time to a window, after it has exited the moving or sizing modal loop. The window enters the moving or sizing modal loop when the user clicks the window's title bar or sizing border, or when the window passes the WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the message specifies the SC_MOV
E or SC_SIZE
value. The operation is complete when DefWindowProc returns.
A window receives this message through its WindowProc function.
WM_GETICONThe WM_GETICON message is sent to a window to retrieve a handle to the large or small icon associated with a window. The system displays the large icon in the ALT+TAB dialog, and the small icon in the window caption.
A window receives this message through its WindowProc function.
WM_GETMINMAXINFOThe WM_GETMINMAXINFO message is sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size.
A window receives this message through its WindowProc function.
WM_INPUTLANGCHANGEThe WM_INPUTLANGCHANGE message is sent to the topmost affected window after an application's input language has been changed. You should make any application-specific settings and pass the message to the DefWindowProc function, which passes the message to all first-level child windows. These child windows can pass the message to DefWindowProc to have it pass the message to their child windows, and so on.
A window receives this message through its WindowProc function.
WM_INPUTLANGCHANGEREQUESTThe WM_INPUTLANGCHANGEREQUEST message is posted to the window with the focus when the user chooses a new input language, either with the hotkey (specified in the Keyboard control panel application) or from the indicator on the system taskbar. An application can accept the change by passing the message to the DefWindowProc function or reject the change (and prevent it from taking place) by returning immediately.
A window receives this message through its WindowProc function.
WM_MOVEThe WM_MOVE message is sent after a window has been moved.
A window receives this message through its WindowProc function.
WM_MOVINGThe WM_MOVING message is sent to a window that the user is moving. By processing this message, an application can monitor the position of the drag rectangle and, if needed, change its position.
A window receives this message through its WindowProc function.
WM_NCACTIVATEThe WM_NCACTIVATE message is sent to a window when its nonclient area needs to be changed to indicate an active or inactive state.
A window receives this message through its WindowProc function.
WM_NCCALCSIZEThe WM_NCCALCSIZE message is sent when the size and position of a window's client area must be calculated. By processing this message, an application can control the content of the window's client area when the size or position of the window changes.
A window receives this message through its WindowProc function.
WM_NCCREATEThe WM_NCCREATE message is sent prior to the WM_CREATE message when a window is first created.
A window receives this message through its WindowProc function.
WM_NCDESTROYThe WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY message. WM_DESTROY is used to free the allocated memory object associated with the window.
The WM_NCDESTROY message is sent after the child windows have been destroyed. In contrast, WM_DESTROY is sent before the child windows are destroyed.
A window receives this message through its WindowProc function.
WM_NULLThe WM_NULL message performs no operation. An application sends the WM_NULL message if it wants to post a message that the recipient window will ignore.
A window receives this message through its WindowProc function.
WM_PARENTNOTIFYThe WM_PARENTNOTIFY message is sent to the parent of a child window when the child window is created or destroyed, or when the user clicks a mouse button while the cursor is over the child window. When the child window is being created, the system sends WM_PARENTNOTIFY just before the CreateWindow or CreateWindowEx function that creates the window returns. When the child window is being destroyed, the system sends the message before any processing to destroy the window takes place.
A window receives this message through its WindowProc function.
WM_QUERYDRAGICONThe WM_QUERYDRAGICON message is sent to a minimized (iconic) window. The window is about to be dragged by the user but does not have an icon defined for its class. An application can return a handle to an icon or cursor. The system displays this cursor or icon while the user drags the icon.
A window receives this message through its WindowProc function.
WM_QUERYOPENThe WM_QUERYOPEN message is sent to an icon when the user requests that the window be restored to its previous size and position.
A window receives this message through its WindowProc function.
WM_SHOWWINDOWThe WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown.
A window receives this message through its WindowProc function.
WM_SIZEThe WM_SIZE message is sent to a window after its size has changed.
A window receives this message through its WindowProc function.
WM_SIZINGThe WM_SIZING message is sent to a window that the user is resizing. By processing this message, an application can monitor the size and position of the drag rectangle and, if needed, change its size or position.
A window receives this message through its WindowProc function.
WM_STYLECHANGEDThe WM_STYLECHANGED message is sent to a window after the SetWindowLong function has changed one or more of the window's styles.
A window receives this message through its WindowProc function.
WM_STYLECHANGINGThe WM_STYLECHANGING message is sent to a window when the SetWindowLong function is about to change one or more of the window's styles.
A window receives this message through its WindowProc function.
WM_THEMECHANGEDThe WM_THEMECHANGED message is broadcast to every window following a theme change event. Examples of theme change events are the activation of a theme, the deactivation of a theme, or a transition from one theme to another.
WM_USERCHANGEDThe WM_USERCHANGED message is sent to all windows after the user has logged on or off. When the user logs on or off, the system updates the user-specific settings. The system sends this message immediately after updating the settings.
A window receives this message through its WindowProc function.
WM_WINDOWPOSCHANGEDThe WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place in the Z order has changed as a result of a call to the SetWindowPos function or another window-management function.
A window receives this message through its WindowProc function.
WM_WINDOWPOSCHANGINGThe WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in the Z order is about to change as a result of a call to the SetWindowPos function or another window-management function.
A window receives this message through its WindowProc function.
/* Window Styles */
#define WS_OVERLAPPED 0x00000000L // 기본 윈도우
#define WS_POPUP 0x80000000L // 팝업 윈도우. WS_CHILD와 함께 쓸 수 없음.
#define WS_CHILD 0x40000000L // 자식 윈도우. WS_POPUP과 함께 쓸 수 없음.
#define WS_MINIMIZE 0x20000000L // 생성시 최소화
#define WS_VISIBLE 0x10000000L
#define WS_DISABLED 0x08000000L // 생성시 사용불가 상태
#define WS_CLIPSIBLINGS 0x04000000L
#define WS_CLIPCHILDREN 0x02000000L
#define WS_MAXIMIZE 0x01000000L // 생성시 최대화
#define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */
#define WS_BORDER 0x00800000L // 얇은 경계선, 크기 조정 불가
#define WS_DLGFRAME 0x00400000L // 두꺼운 경계선, 타이틀바 삽입 불가
#define WS_VSCROLL 0x00200000L // 수직 스크롤바를 가진 윈도우
#define WS_HSCROLL 0x00100000L // 수평 스크롤바를 가진 윈도우
#define WS_SYSMENU 0x00080000L // 시스템 메뉴를 가진 윈도우
#define WS_THICKFRAME 0x00040000L // 두꺼운 경계선, 크기 조절 가능
#define WS_GROUP 0x00020000L // 버튼등의 컨트롤을 그룹 지정할 때에 사용
#define WS_TABSTOP 0x00010000L
#define WS_MINIMIZEBOX 0x00020000L // 최소화 버튼을 생성
#define WS_MAXIMIZEBOX 0x00010000L // 최대화 버튼을 생성
#define WS_TILED WS_OVERLAPPED
#define WS_ICONIC WS_MINIMIZE
#define WS_SIZEBOX WS_THICKFRAME
#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
/* Common Window Styles */
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \
WS_CAPTION | \
WS_SYSMENU | \
WS_THICKFRAME | \
WS_MINIMIZEBOX | \
WS_MAXIMIZEBOX)
#define WS_POPUPWINDOW (WS_POPUP | \
WS_BORDER | \
WS_SYSMENU)
#define WS_CHILDWINDOW (WS_CHILD)
/* Extended Window Styles */
#define WS_EX_DLGMODALFRAME 0x00000001L // 이중 경계선
#define WS_EX_NOPARENTNOTIFY 0x00000004L // 생성/소멸시 WM_PARENTNOTIFY 메세지를 보내지 않음
#define WS_EX_TOPMOST 0x00000008L // 항상 최상위 윈도우
#define WS_EX_ACCEPTFILES 0x00000010L // 드래그되는 파일을 받을 수 있는 윈도우
#define WS_EX_TRANSPARENT 0x00000020L
#if(WINVER >= 0x0400)
#define WS_EX_MDICHILD 0x00000040L // MDI 차일드 윈도우
#define WS_EX_TOOLWINDOW 0x00000080L // 툴바 윈도우
#define WS_EX_WINDOWEDGE 0x00000100L // 양각 윈도우
#define WS_EX_CLIENTEDGE 0x00000200L // 음각 윈도우
#define WS_EX_CONTEXTHELP 0x00000400L // 타이틀바에 ? 버튼 출력
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0400)
#define WS_EX_RIGHT 0x00001000L
#define WS_EX_LEFT 0x00000000L
#define WS_EX_RTLREADING 0x00002000L
#define WS_EX_LTRREADING 0x00000000L
#define WS_EX_LEFTSCROLLBAR 0x00004000L
#define WS_EX_RIGHTSCROLLBAR 0x00000000L
#define WS_EX_CONTROLPARENT 0x00010000L // Tab 키로 차일드 사이를 전환
#define WS_EX_STATICEDGE 0x00020000L // 사용자의 입력을 허용하지 않는 형태
#define WS_EX_APPWINDOW 0x00040000L
#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0500)
#define WS_EX_LAYERED 0x00080000
#endif /* _WIN32_WINNT >= 0x0500 */
#if(WINVER >= 0x0500)
#define WS_EX_NOINHERITLAYOUT 0x00100000L // Disable inheritence of mirroring by children
#define WS_EX_LAYOUTRTL 0x00400000L // Right to left mirroring
#endif /* WINVER >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define WS_EX_COMPOSITED 0x02000000L
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0500)
#define WS_EX_NOACTIVATE 0x08000000L
#endif /* _WIN32_WINNT >= 0x0500 */