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     { &GHOST_builtin_class,     FNID_GHOST,     ICLS_GHOST},
68 };
69 
70 BOOL WINAPI RegisterSystemControls(VOID)
71 {
72     WNDCLASSEXW WndClass;
73     UINT i;
74     ATOM atom;
75 
76     if (RegisterDefaultClasses) return TRUE;
77 
78     ZeroMemory(&WndClass, sizeof(WndClass));
79 
80     WndClass.cbSize = sizeof(WndClass);
81 
82     for (i = 0; i != sizeof(g_SysClasses) / sizeof(g_SysClasses[0]); i++)
83     {
84         WndClass.lpszClassName = g_SysClasses[i].desc->name;
85 
86         // Set Global bit!
87         WndClass.style = g_SysClasses[i].desc->style|CS_GLOBALCLASS;
88         WndClass.lpfnWndProc = g_SysClasses[i].desc->procW;
89         WndClass.cbWndExtra = g_SysClasses[i].desc->extra;
90         WndClass.hCursor = LoadCursorW(NULL, g_SysClasses[i].desc->cursor);
91         WndClass.hbrBackground= g_SysClasses[i].desc->brush;
92 
93         atom = RegisterClassExWOWW( &WndClass,
94                                      0,
95                                      g_SysClasses[i].fnid,
96                                      0,
97                                      FALSE);
98         if (atom)
99            RegisterDefaultClasses |= ICLASS_TO_MASK(g_SysClasses[i].ClsId);
100     }
101 
102     if ( //gpsi->dwSRVIFlags & SRVINFO_IMM32 && Not supported yet, need NlsMbCodePageTag working in Win32k.
103         !(RegisterDefaultClasses & ICLASS_TO_MASK(ICLS_IME))) // So, work like XP.
104     {
105        RegisterIMEClass();
106     }
107 
108     return TRUE;
109 }
110 
111 LRESULT
112 WINAPI
113 MsgWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
114 {
115     PWND pWnd;
116 
117     pWnd = ValidateHwnd(hwnd);
118     if (pWnd)
119     {
120        if (!pWnd->fnid)
121        {
122           NtUserSetWindowFNID(hwnd, FNID_MESSAGEWND);
123        }
124     }
125 
126     if (message == WM_NCCREATE) return TRUE;
127 
128     if (message == WM_DESTROY)
129        NtUserSetWindowFNID(hwnd, FNID_DESTROY);
130 
131     return DefWindowProc(hwnd, message, wParam, lParam );
132 }
133 
134 LRESULT
135 WINAPI
136 DialogWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode)
137 {
138   if (unicode)
139      return DefDlgProcW( hwnd, uMsg, wParam, lParam);
140   return DefDlgProcA( hwnd, uMsg, wParam, lParam);
141 }
142 
143 BOOL WINAPI RegisterClientPFN(VOID)
144 {
145   NTSTATUS Status;
146 
147   pfnClientA.pfnScrollBarWndProc      = ScrollBarWndProcA;
148   pfnClientW.pfnScrollBarWndProc      = ScrollBarWndProcW;
149   pfnClientA.pfnTitleWndProc          = IconTitleWndProc;
150   pfnClientW.pfnTitleWndProc          = IconTitleWndProc;
151   pfnClientA.pfnMenuWndProc           = PopupMenuWndProcA;
152   pfnClientW.pfnMenuWndProc           = PopupMenuWndProcW;
153   pfnClientA.pfnDesktopWndProc        = DesktopWndProcA;
154   pfnClientW.pfnDesktopWndProc        = DesktopWndProcW;
155   pfnClientA.pfnDefWindowProc         = DefWindowProcA;
156   pfnClientW.pfnDefWindowProc         = DefWindowProcW;
157   pfnClientA.pfnMessageWindowProc     = MsgWindowProc;
158   pfnClientW.pfnMessageWindowProc     = MsgWindowProc;
159   pfnClientA.pfnSwitchWindowProc      = SwitchWndProcA;
160   pfnClientW.pfnSwitchWindowProc      = SwitchWndProcW;
161   pfnClientA.pfnButtonWndProc         = ButtonWndProcA;
162   pfnClientW.pfnButtonWndProc         = ButtonWndProcW;
163   pfnClientA.pfnComboBoxWndProc       = ComboWndProcA;
164   pfnClientW.pfnComboBoxWndProc       = ComboWndProcW;
165   pfnClientA.pfnComboListBoxProc      = ListBoxWndProcA;
166   pfnClientW.pfnComboListBoxProc      = ListBoxWndProcW;
167   pfnClientA.pfnDialogWndProc         = DefDlgProcA;
168   pfnClientW.pfnDialogWndProc         = DefDlgProcW;
169   pfnClientA.pfnEditWndProc           = EditWndProcA;
170   pfnClientW.pfnEditWndProc           = EditWndProcW;
171   pfnClientA.pfnListBoxWndProc        = ListBoxWndProcA;
172   pfnClientW.pfnListBoxWndProc        = ListBoxWndProcW;
173   pfnClientA.pfnMDIClientWndProc      = MDIClientWndProcA;
174   pfnClientW.pfnMDIClientWndProc      = MDIClientWndProcW;
175   pfnClientA.pfnStaticWndProc         = StaticWndProcA;
176   pfnClientW.pfnStaticWndProc         = StaticWndProcW;
177   pfnClientA.pfnImeWndProc            = ImeWndProcA;
178   pfnClientW.pfnImeWndProc            = ImeWndProcW;
179   pfnClientA.pfnGhostWndProc          = GhostWndProcA;
180   pfnClientW.pfnGhostWndProc          = GhostWndProcW;
181   pfnClientA.pfnHkINLPCWPSTRUCT       = DefWindowProcA;
182   pfnClientW.pfnHkINLPCWPSTRUCT       = DefWindowProcW;
183   pfnClientA.pfnHkINLPCWPRETSTRUCT    = DefWindowProcA;
184   pfnClientW.pfnHkINLPCWPRETSTRUCT    = DefWindowProcW;
185   pfnClientA.pfnDispatchHook          = DefWindowProcA;
186   pfnClientW.pfnDispatchHook          = DefWindowProcW;
187   pfnClientA.pfnDispatchDefWindowProc = DefWindowProcA;
188   pfnClientW.pfnDispatchDefWindowProc = DefWindowProcW;
189   pfnClientA.pfnDispatchMessage       = DefWindowProcA;
190   pfnClientW.pfnDispatchMessage       = DefWindowProcW;
191   pfnClientA.pfnMDIActivateDlgProc    = DefWindowProcA;
192   pfnClientW.pfnMDIActivateDlgProc    = DefWindowProcW;
193 
194   pfnClientWorker.pfnButtonWndProc    = ButtonWndProc_common;
195   pfnClientWorker.pfnComboBoxWndProc  = ComboWndProc_common;
196   pfnClientWorker.pfnComboListBoxProc = ListBoxWndProc_common;
197   pfnClientWorker.pfnDialogWndProc    = DialogWndProc_common;
198   pfnClientWorker.pfnEditWndProc      = EditWndProc_common;
199   pfnClientWorker.pfnListBoxWndProc   = ListBoxWndProc_common;
200   pfnClientWorker.pfnMDIClientWndProc = MDIClientWndProc_common;
201   pfnClientWorker.pfnStaticWndProc    = StaticWndProc_common;
202   pfnClientWorker.pfnImeWndProc       = ImeWndProc_common;
203   pfnClientWorker.pfnGhostWndProc     = GhostWndProc_common;
204   pfnClientWorker.pfnCtfHookProc      = User32DefWindowProc;
205 
206   Status = NtUserInitializeClientPfnArrays( &pfnClientA,
207                                             &pfnClientW,
208                                             &pfnClientWorker,
209                                             User32Instance);
210 
211   return NT_SUCCESS(Status) ? TRUE : FALSE;
212 }
213