1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS User32
4  * PURPOSE:          Built-in control registration
5  * FILE:             win32ss/user/user32/controls/regcontrol.c
6  * PROGRAMER:        Ge van Geldorp (ge@gse.nl)
7  * REVISION HISTORY: 2003/06/16 GvG Created
8  * NOTES:            Adapted from Wine
9  */
10 
11 #include <user32.h>
12 
13 #include <wine/debug.h>
14 WINE_DEFAULT_DEBUG_CHANNEL(user32);
15 
16 DWORD RegisterDefaultClasses = FALSE;
17 
18 static PFNCLIENT pfnClientA;
19 static PFNCLIENT pfnClientW;
20 static PFNCLIENTWORKER pfnClientWorker;
21 
22 
23 /***********************************************************************
24  *           set_control_clipping
25  *
26  * Set clipping for a builtin control that uses CS_PARENTDC.
27  * Return the previous clip region if any.
28  */
29 HRGN set_control_clipping( HDC hdc, const RECT *rect )
30 {
31     RECT rc = *rect;
32     HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
33 
34     if (GetClipRgn( hdc, hrgn ) != 1)
35     {
36         DeleteObject( hrgn );
37         hrgn = 0;
38     }
39     DPtoLP( hdc, (POINT *)&rc, 2 );
40     if (GetLayout( hdc ) & LAYOUT_RTL)  /* compensate for the shifting done by IntersectClipRect */
41     {
42         rc.left++;
43         rc.right++;
44     }
45     IntersectClipRect( hdc, rc.left, rc.top, rc.right, rc.bottom );
46     return hrgn;
47 }
48 
49 static const struct
50 {
51     const struct builtin_class_descr *desc;
52     WORD fnid;
53     WORD ClsId;
54 } g_SysClasses[] =
55 {
56     { &DIALOG_builtin_class,    FNID_DIALOG,    ICLS_DIALOG},
57 /*    { &POPUPMENU_builtin_class, FNID_MENU,      ICLS_MENU},     // moved to win32k */
58     { &COMBO_builtin_class,     FNID_COMBOBOX,  ICLS_COMBOBOX},
59     { &COMBOLBOX_builtin_class, FNID_COMBOLBOX, ICLS_COMBOLBOX},
60     { &MDICLIENT_builtin_class, FNID_MDICLIENT, ICLS_MDICLIENT},
61 #if 0
62     { &MENU_builtin_class,      FNID_MENU,      ICLS_MENU},
63 #endif
64 /*    { &SCROLL_builtin_class,    FNID_SCROLLBAR, ICLS_SCROLLBAR}, // moved to win32k */
65     { &BUTTON_builtin_class,    FNID_BUTTON,    ICLS_BUTTON},
66     { &LISTBOX_builtin_class,   FNID_LISTBOX,   ICLS_LISTBOX},
67     { &EDIT_builtin_class,      FNID_EDIT,      ICLS_EDIT},
68 /*    { &ICONTITLE_builtin_class, FNID_ICONTITLE, ICLS_ICONTITLE}, // moved to win32k */
69     { &STATIC_builtin_class,    FNID_STATIC,    ICLS_STATIC},
70 };
71 
72 BOOL WINAPI RegisterSystemControls(VOID)
73 {
74     WNDCLASSEXW WndClass;
75     UINT i;
76     ATOM atom;
77 
78     if (RegisterDefaultClasses) return TRUE;
79 
80     ZeroMemory(&WndClass, sizeof(WndClass));
81 
82     WndClass.cbSize = sizeof(WndClass);
83 
84     for (i = 0; i != sizeof(g_SysClasses) / sizeof(g_SysClasses[0]); i++)
85     {
86         WndClass.lpszClassName = g_SysClasses[i].desc->name;
87 
88         // Set Global bit!
89         WndClass.style = g_SysClasses[i].desc->style|CS_GLOBALCLASS;
90         WndClass.lpfnWndProc = g_SysClasses[i].desc->procW;
91         WndClass.cbWndExtra = g_SysClasses[i].desc->extra;
92         WndClass.hCursor = LoadCursorW(NULL, g_SysClasses[i].desc->cursor);
93         WndClass.hbrBackground= g_SysClasses[i].desc->brush;
94 
95         atom = RegisterClassExWOWW( &WndClass,
96                                      0,
97                                      g_SysClasses[i].fnid,
98                                      0,
99                                      FALSE);
100         if (atom)
101            RegisterDefaultClasses |= ICLASS_TO_MASK(g_SysClasses[i].ClsId);
102     }
103 
104     if ( //gpsi->dwSRVIFlags & SRVINFO_IMM32 && Not supported yet, need NlsMbCodePageTag working in Win32k.
105         !(RegisterDefaultClasses & ICLASS_TO_MASK(ICLS_IME))) // So, work like XP.
106     {
107        RegisterIMEClass();
108     }
109 
110     return TRUE;
111 }
112 
113 LRESULT
114 WINAPI
115 MsgWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
116 {
117     PWND pWnd;
118 
119     pWnd = ValidateHwnd(hwnd);
120     if (pWnd)
121     {
122        if (!pWnd->fnid)
123        {
124           NtUserSetWindowFNID(hwnd, FNID_MESSAGEWND);
125        }
126     }
127 
128     if (message == WM_NCCREATE) return TRUE;
129 
130     if (message == WM_DESTROY)
131        NtUserSetWindowFNID(hwnd, FNID_DESTROY);
132 
133     return DefWindowProc(hwnd, message, wParam, lParam );
134 }
135 
136 LRESULT
137 WINAPI
138 DialogWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode)
139 {
140   if (unicode)
141      return DefDlgProcW( hwnd, uMsg, wParam, lParam);
142   return DefDlgProcA( hwnd, uMsg, wParam, lParam);
143 }
144 
145 BOOL WINAPI RegisterClientPFN(VOID)
146 {
147   NTSTATUS Status;
148 
149   pfnClientA.pfnScrollBarWndProc      = ScrollBarWndProcA;
150   pfnClientW.pfnScrollBarWndProc      = ScrollBarWndProcW;
151   pfnClientA.pfnTitleWndProc          = IconTitleWndProc;
152   pfnClientW.pfnTitleWndProc          = IconTitleWndProc;
153   pfnClientA.pfnMenuWndProc           = PopupMenuWndProcA;
154   pfnClientW.pfnMenuWndProc           = PopupMenuWndProcW;
155   pfnClientA.pfnDesktopWndProc        = DesktopWndProcA;
156   pfnClientW.pfnDesktopWndProc        = DesktopWndProcW;
157   pfnClientA.pfnDefWindowProc         = DefWindowProcA;
158   pfnClientW.pfnDefWindowProc         = DefWindowProcW;
159   pfnClientA.pfnMessageWindowProc     = MsgWindowProc;
160   pfnClientW.pfnMessageWindowProc     = MsgWindowProc;
161   pfnClientA.pfnSwitchWindowProc      = SwitchWndProcA;
162   pfnClientW.pfnSwitchWindowProc      = SwitchWndProcW;
163   pfnClientA.pfnButtonWndProc         = ButtonWndProcA;
164   pfnClientW.pfnButtonWndProc         = ButtonWndProcW;
165   pfnClientA.pfnComboBoxWndProc       = ComboWndProcA;
166   pfnClientW.pfnComboBoxWndProc       = ComboWndProcW;
167   pfnClientA.pfnComboListBoxProc      = ListBoxWndProcA;
168   pfnClientW.pfnComboListBoxProc      = ListBoxWndProcW;
169   pfnClientA.pfnDialogWndProc         = DefDlgProcA;
170   pfnClientW.pfnDialogWndProc         = DefDlgProcW;
171   pfnClientA.pfnEditWndProc           = EditWndProcA;
172   pfnClientW.pfnEditWndProc           = EditWndProcW;
173   pfnClientA.pfnListBoxWndProc        = ListBoxWndProcA;
174   pfnClientW.pfnListBoxWndProc        = ListBoxWndProcW;
175   pfnClientA.pfnMDIClientWndProc      = MDIClientWndProcA;
176   pfnClientW.pfnMDIClientWndProc      = MDIClientWndProcW;
177   pfnClientA.pfnStaticWndProc         = StaticWndProcA;
178   pfnClientW.pfnStaticWndProc         = StaticWndProcW;
179   pfnClientA.pfnImeWndProc            = ImeWndProcA;
180   pfnClientW.pfnImeWndProc            = ImeWndProcW;
181   pfnClientA.pfnGhostWndProc          = DefWindowProcA;
182   pfnClientW.pfnGhostWndProc          = DefWindowProcW;
183   pfnClientA.pfnHkINLPCWPSTRUCT       = DefWindowProcA;
184   pfnClientW.pfnHkINLPCWPSTRUCT       = DefWindowProcW;
185   pfnClientA.pfnHkINLPCWPRETSTRUCT    = DefWindowProcA;
186   pfnClientW.pfnHkINLPCWPRETSTRUCT    = DefWindowProcW;
187   pfnClientA.pfnDispatchHook          = DefWindowProcA;
188   pfnClientW.pfnDispatchHook          = DefWindowProcW;
189   pfnClientA.pfnDispatchDefWindowProc = DefWindowProcA;
190   pfnClientW.pfnDispatchDefWindowProc = DefWindowProcW;
191   pfnClientA.pfnDispatchMessage       = DefWindowProcA;
192   pfnClientW.pfnDispatchMessage       = DefWindowProcW;
193   pfnClientA.pfnMDIActivateDlgProc    = DefWindowProcA;
194   pfnClientW.pfnMDIActivateDlgProc    = DefWindowProcW;
195 
196   pfnClientWorker.pfnButtonWndProc    = ButtonWndProc_common;
197   pfnClientWorker.pfnComboBoxWndProc  = ComboWndProc_common;
198   pfnClientWorker.pfnComboListBoxProc = ListBoxWndProc_common;
199   pfnClientWorker.pfnDialogWndProc    = DialogWndProc_common;
200   pfnClientWorker.pfnEditWndProc      = EditWndProc_common;
201   pfnClientWorker.pfnListBoxWndProc   = ListBoxWndProc_common;
202   pfnClientWorker.pfnMDIClientWndProc = MDIClientWndProc_common;
203   pfnClientWorker.pfnStaticWndProc    = StaticWndProc_common;
204   pfnClientWorker.pfnImeWndProc       = ImeWndProc_common;
205   pfnClientWorker.pfnGhostWndProc     = User32DefWindowProc;
206   pfnClientWorker.pfnCtfHookProc      = User32DefWindowProc;
207 
208   Status = NtUserInitializeClientPfnArrays( &pfnClientA,
209                                             &pfnClientW,
210                                             &pfnClientWorker,
211                                             User32Instance);
212 
213   return NT_SUCCESS(Status) ? TRUE : FALSE;
214 }
215