source: trunk/src/user32/windlgmsg.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 11.6 KB
RevLine 
[8968]1/* $Id: windlgmsg.cpp,v 1.16 2002-08-08 12:34:37 sandervl Exp $ */
[2469]2/*
3 * Win32 dialog message APIs for OS/2
4 *
5 * Copyright 1999 Sander van Leeuwen (OS/2 port & adaption)
6 *
[3153]7 * Based on Corel WINE code (20000317: window\dialog.c)
8 * (Based on Wine code (990815: window\dialog.c))
[2469]9 *
10 * Copyright 1993, 1994, 1996 Alexandre Julliard
11 *
12 * TODO: Dialog accelerator
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17#include <os2win.h>
18#include <misc.h>
19#include <string.h>
20#include <ctype.h>
21#include "win32wbase.h"
22#include "win32dlg.h"
[7506]23#include <winnls.h>
[21916]24#include <wine/unicode.h>
[2469]25
[3153]26#define DBG_LOCALLOG DBG_windlgmsg
[2803]27#include "dbglocal.h"
28
[2469]29//******************************************************************************
30//******************************************************************************
31LONG WIN32API SendDlgItemMessageA( HWND hwnd, int id, UINT Msg, WPARAM wParam, LPARAM lParam)
32{
33 Win32Dialog *dialog;
[5935]34 HWND hwndDlgItem;
[2469]35
36 dialog = (Win32Dialog *)Win32BaseWindow::GetWindowFromHandle(hwnd);
37 if(!dialog) {
38 dprintf(("SendDlgItemMessageA, window %x not found", hwnd));
39 return 0;
40 }
[5935]41 hwndDlgItem = dialog->getDlgItem(id);
42 RELEASE_WNDOBJ(dialog);
43 if(hwndDlgItem) {
44 return SendMessageA(hwndDlgItem, Msg, wParam, lParam);
[2469]45 }
46 return 0;
47}
48//******************************************************************************
49//******************************************************************************
50LONG WIN32API SendDlgItemMessageW( HWND hwnd, int id, UINT Msg, WPARAM wParam, LPARAM lParam)
51{
52 Win32Dialog *dialog;
[5935]53 HWND hwndDlgItem;
[2469]54
55 dialog = (Win32Dialog *)Win32BaseWindow::GetWindowFromHandle(hwnd);
56 if(!dialog) {
57 dprintf(("SendDlgItemMessageW, window %x not found", hwnd));
58 return 0;
59 }
[5935]60 hwndDlgItem = dialog->getDlgItem(id);
61 RELEASE_WNDOBJ(dialog);
62 if(hwndDlgItem) {
63 return SendMessageW(hwndDlgItem, Msg, wParam, lParam);
[2469]64 }
65 return 0;
66}
67/***********************************************************************
68 * DIALOG_IsAccelerator
69 */
70static BOOL DIALOG_IsAccelerator( HWND hwnd, HWND hwndDlg, WPARAM vKey )
71{
72 HWND hwndControl = hwnd;
73 HWND hwndNext;
74 BOOL RetVal = FALSE;
[7506]75 WCHAR buffer[128];
[2469]76 INT dlgCode;
77
[8452]78#ifdef __WIN32OS2__
79 //@PF: Experimental DIALOG_IsAccelerator fix; return FALSE if window is not visible
80 //(fixes endless loop in property sheet when switching page with keyboard)
81 if (!IsWindowVisible(hwnd))
82 return FALSE;
83#endif
84
[2469]85 if (vKey == VK_SPACE)
86 {
87 dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 );
88 if (dlgCode & DLGC_BUTTON)
89 {
[7506]90 /* send BM_CLICK message to the control */
91 SendMessageA( hwndControl, BM_CLICK, 0, 0 );
92 return TRUE;
[2469]93 }
94 }
[7506]95
96 do
[2469]97 {
[7506]98 DWORD style = GetWindowLongW( hwndControl, GWL_STYLE );
99 if ((style & (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE)
[2469]100 {
[7506]101 dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 );
102 if ( (dlgCode & (DLGC_BUTTON | DLGC_STATIC)) &&
103 GetWindowTextW( hwndControl, buffer, sizeof(buffer)/sizeof(WCHAR) ))
[2469]104 {
[7506]105 /* find the accelerator key */
106 LPWSTR p = buffer - 2;
107 char a_char = vKey;
108 WCHAR w_char = 0;
109
110 do
[2469]111 {
[7506]112 p = strchrW( p + 2, '&' );
113 }
114 while (p != NULL && p[1] == '&');
[2469]115
[7506]116 /* and check if it's the one we're looking for */
117 MultiByteToWideChar(CP_ACP, 0, &a_char, 1, &w_char, 1);
118 if (p != NULL && toupperW( p[1] ) == toupperW( w_char ) )
119 {
120 if ((dlgCode & DLGC_STATIC) || (style & 0x0f) == BS_GROUPBOX )
[2469]121 {
[7506]122 /* set focus to the control */
123 SendMessageA( hwndDlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, 1);
124 /* and bump it on to next */
125 SendMessageA( hwndDlg, WM_NEXTDLGCTL, 0, 0);
[5935]126 }
[7506]127 else if (dlgCode & DLGC_BUTTON)
128 {
129 /* send BM_CLICK message to the control */
130 SendMessageA( hwndControl, BM_CLICK, 0, 0 );
131 }
132 return TRUE;
[5935]133 }
134 }
[7506]135 hwndNext = GetWindow( hwndControl, GW_CHILD );
136 }
137 else hwndNext = 0;
[5935]138
[7506]139 if (!hwndNext) hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
140
141 while (!hwndNext && hwndControl)
142 {
143 hwndControl = GetParent( hwndControl );
144 if (hwndControl == hwndDlg)
[5935]145 {
[7506]146 if(hwnd==hwndDlg) /* prevent endless loop */
[5935]147 {
[7506]148 hwndNext=hwnd;
149 break;
[2469]150 }
[7506]151 hwndNext = GetWindow( hwndDlg, GW_CHILD );
152 }
153 else
[6751]154#ifdef __WIN32OS2__
[7506]155 {
156 if(hwndControl == 0) {
157 dprintf(("WARNING: DIALOG_IsAccelerator %x %x -> hwndControl == 0", hwnd, hwndDlg));
158 return FALSE;
[5935]159 }
[7506]160 hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
[2469]161 }
[7506]162#else
163 hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
164#endif
[2469]165 }
[7506]166 hwndControl = hwndNext;
[2469]167 }
[7506]168 while (hwndControl && (hwndControl != hwnd));
169
170 return FALSE;
[2469]171}
172/***********************************************************************
[3153]173 * DIALOG_FindMsgDestination
174 *
175 * The messages that IsDialogMessage send may not go to the dialog
176 * calling IsDialogMessage if that dialog is a child, and it has the
177 * DS_CONTROL style set.
178 * We propagate up until we hit a that does not have DS_CONTROL, or
179 * whose parent is not a dialog.
[5935]180 *
181 * This is undocumented behaviour.
[3153]182 */
183static HWND DIALOG_FindMsgDestination( HWND hwndDlg )
184{
185 while (GetWindowLongA(hwndDlg, GWL_STYLE) & DS_CONTROL)
186 {
187 Win32BaseWindow *pParent;
188 HWND hParent = GetParent(hwndDlg);
189 if (!hParent) break;
190
191 pParent = Win32BaseWindow::GetWindowFromHandle(hParent);
192 if (!pParent) break;
193
[5935]194 if (!pParent->IsDialog()) {
195 RELEASE_WNDOBJ(pParent);
196 break;
197 }
198 RELEASE_WNDOBJ(pParent);
[3153]199 hwndDlg = hParent;
200 }
201
202 return hwndDlg;
203}
204
205/***********************************************************************
[2469]206 * DIALOG_IsDialogMessage
207 */
[3153]208static BOOL DIALOG_IsDialogMessage( HWND hwndDlg, BOOL *translate, BOOL *dispatch, INT dlgCode, LPMSG msg )
[2469]209{
210 *translate = *dispatch = FALSE;
211
[3153]212 if (msg->message == WM_PAINT)
[2469]213 {
214 /* Apparently, we have to handle this one as well */
215 *dispatch = TRUE;
216 return TRUE;
217 }
218
219 /* Only the key messages get special processing */
[3153]220 if ((msg->message != WM_KEYDOWN) &&
221 (msg->message != WM_SYSCHAR) &&
222 (msg->message != WM_CHAR))
[8812]223 {
224#ifdef __WIN32OS2__
225 *translate = *dispatch = TRUE;
226 return TRUE;
227#else
[2469]228 return FALSE;
[8812]229#endif
230 }
[2469]231
232 if (dlgCode & DLGC_WANTMESSAGE)
233 {
234 *translate = *dispatch = TRUE;
235 return TRUE;
236 }
237
[3153]238 hwndDlg = DIALOG_FindMsgDestination(hwndDlg);
239
240 switch(msg->message)
[2469]241 {
242 case WM_KEYDOWN:
[3153]243 switch(msg->wParam)
[2469]244 {
245 case VK_TAB:
246 if (!(dlgCode & DLGC_WANTTAB))
247 {
248 SendMessageA( hwndDlg, WM_NEXTDLGCTL,
249 (GetKeyState(VK_SHIFT) & 0x8000), 0 );
250 return TRUE;
251 }
252 break;
253
254 case VK_RIGHT:
255 case VK_DOWN:
256 case VK_LEFT:
257 case VK_UP:
258 if (!(dlgCode & DLGC_WANTARROWS))
259 {
[3153]260 BOOL fPrevious = (msg->wParam == VK_LEFT || msg->wParam == VK_UP);
[2469]261 HWND hwndNext =
262 GetNextDlgGroupItem (hwndDlg, GetFocus(), fPrevious );
263 SendMessageA( hwndDlg, WM_NEXTDLGCTL, hwndNext, 1 );
264 return TRUE;
265 }
266 break;
267
268 case VK_ESCAPE:
269 SendMessageA( hwndDlg, WM_COMMAND, IDCANCEL,
270 (LPARAM)GetDlgItem( hwndDlg, IDCANCEL ) );
271 return TRUE;
272
273 case VK_RETURN:
274 {
275 DWORD dw = SendMessageA( hwndDlg, DM_GETDEFID, 0, 0 );
276 if (HIWORD(dw) == DC_HASDEFID)
277 {
[21916]278 if (IsWindowEnabled(GetDlgItem(hwndDlg, LOWORD(dw))))
[8968]279 {
[8501]280 SendMessageA( hwndDlg, WM_COMMAND,
281 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
[2469]282 (LPARAM)GetDlgItem(hwndDlg, LOWORD(dw)));
[8968]283 }
[2469]284 }
285 else
286 {
[8968]287 // @@PF Win2k here behaves this way: checks focus and then
288 // if it is button clicks it, I also added enabled check
289 HWND hwndCtrl = GetFocus();
290 if (SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON)
291 {
292 if (IsWindowEnabled(hwndCtrl))
293 SendMessageA( hwndDlg, WM_COMMAND,
294 MAKEWPARAM( GetDlgCtrlID(hwndCtrl), BN_CLICKED ),
295 (LPARAM)hwndCtrl);
296 }
297 else
298 SendMessageA( hwndDlg, WM_COMMAND, IDOK,
[2469]299 (LPARAM)GetDlgItem( hwndDlg, IDOK ) );
300 }
[3153]301
302 return TRUE;
[2469]303 }
304 }
305 *translate = TRUE;
306 break; /* case WM_KEYDOWN */
307
308 case WM_CHAR:
309 if (dlgCode & DLGC_WANTCHARS) break;
310 /* drop through */
311
312 case WM_SYSCHAR:
[3153]313 if (DIALOG_IsAccelerator( msg->hwnd, hwndDlg, msg->wParam ))
[2469]314 {
315 /* don't translate or dispatch */
316 return TRUE;
317 }
318 break;
319 }
320
321 /* If we get here, the message has not been treated specially */
322 /* and can be sent to its destination window. */
323 *dispatch = TRUE;
324 return TRUE;
325}
326//******************************************************************************
327//******************************************************************************
328BOOL WIN32API IsDialogMessageA( HWND hwndDlg, LPMSG msg)
329{
330 BOOL ret, translate, dispatch;
331 INT dlgCode;
332
333 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd ))
334 return FALSE;
335
[8802]336#ifdef __WIN32OS2__
337 if(CallMsgFilterA(msg, HC_ACTION)) {
338 return TRUE;
339 }
340#endif
341
[2469]342 dlgCode = SendMessageA( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg);
[3153]343 ret = DIALOG_IsDialogMessage(hwndDlg,&translate,&dispatch,dlgCode,msg);
[2469]344 if (translate) TranslateMessage( msg );
345 if (dispatch) DispatchMessageA( msg );
346
347 return ret;
348}
349//******************************************************************************
350//******************************************************************************
351BOOL WIN32API IsDialogMessageW(HWND hwndDlg, LPMSG msg)
352{
353 BOOL ret, translate, dispatch;
354 INT dlgCode;
355
356 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd ))
357 return FALSE;
358
[8802]359#ifdef __WIN32OS2__
360 if(CallMsgFilterW(msg, HC_ACTION)) {
361 return TRUE;
362 }
363#endif
364
[2469]365 dlgCode = SendMessageW( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg);
[3153]366 ret = DIALOG_IsDialogMessage(hwndDlg,&translate,&dispatch,dlgCode,msg);
[2469]367 if (translate) TranslateMessage( msg );
368 if (dispatch) DispatchMessageW( msg );
369 return ret;
370}
371//******************************************************************************
372//******************************************************************************
Note: See TracBrowser for help on using the repository browser.