source: trunk/src/user32/windlgmsg.cpp@ 7788

Last change on this file since 7788 was 7506, checked in by sandervl, 24 years ago

DIALOG_IsAccelerator resync (Wine)

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