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