- Timestamp:
- Aug 23, 1999, 11:42:08 AM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/user32/new/dialog.cpp
r300 r643 1 /* $Id: dialog.cpp,v 1.1 1999-07-14 08:35:34 sandervl Exp $ */2 3 1 /* 4 * Win32 dialog API functions for OS/22 * Dialog functions 5 3 * 6 * Copyright 1998 Sander van Leeuwen 4 * Copyright 1993, 1994, 1996 Alexandre Julliard 5 */ 6 7 #include <os2win.h> 8 #include <ctype.h> 9 #include <errno.h> 10 #include <limits.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <stdio.h> 14 #include <heapstring.h> 15 #include <winuser.h> 16 //#include "windowsx.h" 17 //#include "wine/winuser16.h" 18 //#include "wine/winbase16.h" 19 #include "dialog.h" 20 //#include "drive.h" 21 #include "heap.h" 22 #include "win.h" 23 #include "ldt.h" 24 #include "user.h" 25 #include "winproc.h" 26 //#include "message.h" 27 //#include "debugtools.h" 28 29 //ODINDEBUGCHANNEL(USER32-DIALOG) 30 31 32 /* Dialog control information */ 33 typedef struct 34 { 35 DWORD style; 36 DWORD exStyle; 37 DWORD helpId; 38 INT16 x; 39 INT16 y; 40 INT16 cx; 41 INT16 cy; 42 UINT id; 43 LPCSTR className; 44 LPCSTR windowName; 45 LPVOID data; 46 } DLG_CONTROL_INFO; 47 48 /* Dialog template */ 49 typedef struct 50 { 51 DWORD style; 52 DWORD exStyle; 53 DWORD helpId; 54 UINT16 nbItems; 55 INT16 x; 56 INT16 y; 57 INT16 cx; 58 INT16 cy; 59 LPCSTR menuName; 60 LPCSTR className; 61 LPCSTR caption; 62 WORD pointSize; 63 WORD weight; 64 BOOL italic; 65 LPCSTR faceName; 66 BOOL dialogEx; 67 } DLG_TEMPLATE; 68 69 /* Radio button group */ 70 typedef struct 71 { 72 UINT firstID; 73 UINT lastID; 74 UINT checkID; 75 } RADIOGROUP; 76 77 /* Dialog base units */ 78 static WORD xBaseUnit = 0, yBaseUnit = 0; 79 80 81 /*********************************************************************** 82 * DIALOG_GetCharSizeFromDC 7 83 * 8 84 * 9 * Project Odin Software License can be found in LICENSE.TXT 85 * Calculates the *true* average size of English characters in the 86 * specified font as oppposed to the one returned by GetTextMetrics. 87 */ 88 static BOOL DIALOG_GetCharSizeFromDC( HDC hDC, HFONT hFont, SIZE * pSize ) 89 { 90 BOOL Success = FALSE; 91 HFONT hFontPrev = 0; 92 pSize->cx = xBaseUnit; 93 pSize->cy = yBaseUnit; 94 if ( hDC ) 95 { 96 /* select the font */ 97 TEXTMETRICA tm; 98 memset(&tm,0,sizeof(tm)); 99 if (hFont) hFontPrev = SelectFont(hDC,hFont); 100 if (GetTextMetricsA(hDC,&tm)) 101 { 102 pSize->cx = tm.tmAveCharWidth; 103 pSize->cy = tm.tmHeight; 104 105 /* if variable width font */ 106 if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) 107 { 108 SIZE total; 109 static const char szAvgChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 110 111 /* Calculate a true average as opposed to the one returned 112 * by tmAveCharWidth. This works better when dealing with 113 * proportional spaced fonts and (more important) that's 114 * how Microsoft's dialog creation code calculates the size 115 * of the font 116 */ 117 if (GetTextExtentPointA(hDC,szAvgChars,sizeof(szAvgChars),&total)) 118 { 119 /* round up */ 120 pSize->cx = ((2*total.cx/sizeof(szAvgChars)) + 1)/2; 121 Success = TRUE; 122 } 123 } 124 else 125 { 126 Success = TRUE; 127 } 128 } 129 130 /* select the original font */ 131 if (hFontPrev) SelectFont(hDC,hFontPrev); 132 } 133 return (Success); 134 } 135 136 137 /*********************************************************************** 138 * DIALOG_GetCharSize 10 139 * 11 */ 12 #include <os2win.h> 13 #include <nameid.h> 14 #include "user32.h" 15 #include "wndproc.h" 16 #include "wndclass.h" 17 18 //****************************************************************************** 19 //****************************************************************************** 20 HWND WIN32API CreateDialogParamA(HINSTANCE hinst, LPCSTR lpszTemplate, 21 HWND hwndOwner, DLGPROC dlgproc, 22 LPARAM lParamInit) 23 { 24 HWND rc; 25 26 if((int)lpszTemplate >> 16 != 0) {//convert string name identifier to numeric id 27 #ifdef DEBUG 28 WriteLog("OS2CreateDialogParamA %s\n", lpszTemplate); 29 #endif 30 lpszTemplate = (LPCSTR)ConvertNameId(hinst, (char *)lpszTemplate); 31 } 32 #ifdef DEBUG 33 else WriteLog("OS2CreateDialogParamA %d\n", (int)lpszTemplate); 34 #endif 35 36 return(rc); 37 } 38 //****************************************************************************** 39 //****************************************************************************** 40 HWND WIN32API CreateDialogParamW(HINSTANCE hinst, LPCWSTR lpszTemplate, 41 HWND hwndOwner, DLGPROC dlgproc, 42 LPARAM lParamInit) 43 { 44 HWND rc; 45 46 if((int)lpszTemplate >> 16 != 0) {//convert string name identifier to numeric id 47 char *astring = UnicodeToAsciiString((LPWSTR)lpszTemplate); 48 #ifdef DEBUG 49 WriteLog("OS2CreateDialogParamW %s\n", astring); 50 #endif 51 lpszTemplate = (LPWSTR)ConvertNameId(hinst, astring); 52 FreeAsciiString(astring); 53 } 54 #ifdef DEBUG 55 else WriteLog("OS2CreateDialogParamW %d\n", (int)lpszTemplate); 56 #endif 57 58 return(rc); 59 } 60 //****************************************************************************** 61 //****************************************************************************** 62 HWND WIN32API CreateDialogIndirectParamA(HINSTANCE hinst, 63 DLGTEMPLATE *dlgtemplate, 64 HWND hwndParent, DLGPROC dlgproc, 65 LPARAM lParamInit) 66 { 67 HWND hwnd; 68 69 return(0); 70 } 71 //****************************************************************************** 72 //****************************************************************************** 73 HWND WIN32API CreateDialogIndirectParamW(HINSTANCE hinst, 74 DLGTEMPLATE *dlgtemplate, 75 HWND hwndParent, DLGPROC dlgproc, 76 LPARAM lParamInit) 77 { 78 HWND hwnd; 79 80 return(0); 81 } 82 //****************************************************************************** 83 //****************************************************************************** 84 BOOL WIN32API DialogBoxIndirectParamA(HINSTANCE hinst, 85 DLGTEMPLATE *dlgtemplate, 86 HWND hwndParent, DLGPROC dlgproc, 87 LPARAM lParamInit) 88 { 89 return(0); 90 } 91 //****************************************************************************** 92 //****************************************************************************** 93 BOOL WIN32API DialogBoxIndirectParamW(HINSTANCE hinst, 94 DLGTEMPLATE *dlgtemplate, 95 HWND hwndParent, DLGPROC dlgproc, 96 LPARAM lParamInit) 97 { 98 return(0); 99 } 100 //****************************************************************************** 101 //****************************************************************************** 102 int WIN32API DialogBoxParamA(HINSTANCE hinst, LPCSTR lpszTemplate, HWND hwndOwner, 103 DLGPROC dlgprc, LPARAM lParamInit) 104 { 105 int rc; 106 107 if((int)lpszTemplate >> 16 != 0) {//convert string name identifier to numeric id 108 dprintf(("DialogBoxParam %s\n", lpszTemplate)); 109 lpszTemplate = (LPCSTR)ConvertNameId(hinst, (char *)lpszTemplate); 110 } 111 else { 112 dprintf(("DialogBoxParam %d\n", (int)lpszTemplate)); 113 } 114 115 return(0); 116 } 117 //****************************************************************************** 118 //****************************************************************************** 119 int WIN32API DialogBoxParamW(HINSTANCE arg1, LPCWSTR arg2, HWND arg3, 120 DLGPROC arg4, LPARAM arg5) 121 { 122 int rc; 123 char *astring = NULL; 124 125 126 if((int)arg2 >> 16 != 0) { 127 astring = UnicodeToAsciiString((LPWSTR)arg2); 128 } 129 else astring = (char *)arg2; 130 dprintf(("OS2DialogBoxParamW\n")); 131 132 if((int)astring >> 16 != 0) FreeAsciiString(astring); 133 134 dprintf(("OS2DialogBoxIndirectParamA returned %d\n", rc)); 135 136 return(0); 137 } 138 //****************************************************************************** 139 //****************************************************************************** 140 140 * 141 * Calculates the *true* average size of English characters in the 142 * specified font as oppposed to the one returned by GetTextMetrics. 143 * A convenient variant of DIALOG_GetCharSizeFromDC. 144 */ 145 static BOOL DIALOG_GetCharSize( HFONT hFont, SIZE * pSize ) 146 { 147 HDC hDC = GetDC(0); 148 BOOL Success = DIALOG_GetCharSizeFromDC( hDC, hFont, pSize ); 149 ReleaseDC(0, hDC); 150 return Success; 151 } 152 153 154 /*********************************************************************** 155 * DIALOG_Init 156 * 157 * Initialisation of the dialog manager. 158 */ 159 BOOL DIALOG_Init(void) 160 { 161 HDC16 hdc; 162 SIZE size; 163 164 /* Calculate the dialog base units */ 165 166 if (!(hdc = CreateDC16( "DISPLAY", NULL, NULL, NULL ))) return FALSE; 167 if (!DIALOG_GetCharSizeFromDC( hdc, 0, &size )) return FALSE; 168 DeleteDC( hdc ); 169 xBaseUnit = size.cx; 170 yBaseUnit = size.cy; 171 172 dprintf(("USER32: base units = %d,%d\n", xBaseUnit, yBaseUnit )); 173 return TRUE; 174 } 175 176 177 /*********************************************************************** 178 * DIALOG_GetControl16 179 * 180 * Return the class and text of the control pointed to by ptr, 181 * fill the header structure and return a pointer to the next control. 182 */ 183 static LPCSTR DIALOG_GetControl16( LPCSTR p, DLG_CONTROL_INFO *info ) 184 { 185 static char buffer[10]; 186 int int_id; 187 188 info->x = GET_WORD(p); p += sizeof(WORD); 189 info->y = GET_WORD(p); p += sizeof(WORD); 190 info->cx = GET_WORD(p); p += sizeof(WORD); 191 info->cy = GET_WORD(p); p += sizeof(WORD); 192 info->id = GET_WORD(p); p += sizeof(WORD); 193 info->style = GET_DWORD(p); p += sizeof(DWORD); 194 info->exStyle = 0; 195 196 if (*p & 0x80) 197 { 198 switch((BYTE)*p) 199 { 200 case 0x80: strcpy( buffer, "BUTTON" ); break; 201 case 0x81: strcpy( buffer, "EDIT" ); break; 202 case 0x82: strcpy( buffer, "STATIC" ); break; 203 case 0x83: strcpy( buffer, "LISTBOX" ); break; 204 case 0x84: strcpy( buffer, "SCROLLBAR" ); break; 205 case 0x85: strcpy( buffer, "COMBOBOX" ); break; 206 default: buffer[0] = '\0'; break; 207 } 208 info->className = buffer; 209 p++; 210 } 211 else 212 { 213 info->className = p; 214 p += strlen(p) + 1; 215 } 216 217 int_id = ((BYTE)*p == 0xff); 218 if (int_id) 219 { 220 /* Integer id, not documented (?). Only works for SS_ICON controls */ 221 info->windowName = (LPCSTR)(UINT)GET_WORD(p+1); 222 p += 3; 223 } 224 else 225 { 226 info->windowName = p; 227 p += strlen(p) + 1; 228 } 229 230 info->data = (LPVOID)(*p ? p + 1 : NULL); /* FIXME: should be a segptr */ 231 p += *p + 1; 232 233 if(int_id) 234 dprintf(("USER32: %s %04x %d, %d, %d, %d, %d, %08lx, %08lx\n", 235 info->className, LOWORD(info->windowName), 236 info->id, info->x, info->y, info->cx, info->cy, 237 info->style, (DWORD)info->data)); 238 else 239 dprintf(("USER32: %s '%s' %d, %d, %d, %d, %d, %08lx, %08lx\n", 240 info->className, info->windowName, 241 info->id, info->x, info->y, info->cx, info->cy, 242 info->style, (DWORD)info->data)); 243 244 return p; 245 } 246 247 248 /*********************************************************************** 249 * DIALOG_GetControl32 250 * 251 * Return the class and text of the control pointed to by ptr, 252 * fill the header structure and return a pointer to the next control. 253 */ 254 static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info, 255 BOOL dialogEx ) 256 { 257 if (dialogEx) 258 { 259 info->helpId = GET_DWORD(p); p += 2; 260 info->exStyle = GET_DWORD(p); p += 2; 261 info->style = GET_DWORD(p); p += 2; 262 } 263 else 264 { 265 info->helpId = 0; 266 info->style = GET_DWORD(p); p += 2; 267 info->exStyle = GET_DWORD(p); p += 2; 268 } 269 info->x = GET_WORD(p); p++; 270 info->y = GET_WORD(p); p++; 271 info->cx = GET_WORD(p); p++; 272 info->cy = GET_WORD(p); p++; 273 274 if (dialogEx) 275 { 276 /* id is a DWORD for DIALOGEX */ 277 info->id = GET_DWORD(p); 278 p += 2; 279 } 280 else 281 { 282 info->id = GET_WORD(p); 283 p++; 284 } 285 286 if (GET_WORD(p) == 0xffff) 287 { 288 static const WCHAR class_names[6][10] = 289 { 290 { 'B','u','t','t','o','n', }, /* 0x80 */ 291 { 'E','d','i','t', }, /* 0x81 */ 292 { 'S','t','a','t','i','c', }, /* 0x82 */ 293 { 'L','i','s','t','B','o','x', }, /* 0x83 */ 294 { 'S','c','r','o','l','l','B','a','r', }, /* 0x84 */ 295 { 'C','o','m','b','o','B','o','x', } /* 0x85 */ 296 }; 297 WORD id = GET_WORD(p+1); 298 if ((id >= 0x80) && (id <= 0x85)) 299 info->className = (LPCSTR)class_names[id - 0x80]; 300 else 301 { 302 info->className = NULL; 303 dprintf(("USER32: Error-Unknown built-in class id %04x\n", id )); 304 } 305 p += 2; 306 } 307 else 308 { 309 info->className = (LPCSTR)p; 310 p += lstrlenW( (LPCWSTR)p ) + 1; 311 } 312 313 if (GET_WORD(p) == 0xffff) /* Is it an integer id? */ 314 { 315 info->windowName = (LPCSTR)(UINT)GET_WORD(p + 1); 316 p += 2; 317 } 318 else 319 { 320 info->windowName = (LPCSTR)p; 321 p += lstrlenW( (LPCWSTR)p ) + 1; 322 } 323 324 dprintf(("USER32: %ls %ls %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", 325 (LPCWSTR)info->className, 326 (LPCWSTR)info->windowName, 327 info->id, info->x, info->y, info->cx, info->cy, 328 info->style, info->exStyle, info->helpId )); 329 330 if (GET_WORD(p)) 331 { 332 info->data = (LPVOID)(p + 1); 333 p += GET_WORD(p) / sizeof(WORD); 334 } 335 else info->data = NULL; 336 p++; 337 338 /* Next control is on dword boundary */ 339 return (const WORD *)((((int)p) + 3) & ~3); 340 } 341 342 343 /*********************************************************************** 344 * DIALOG_CreateControls 345 * 346 * Create the control windows for a dialog. 347 */ 348 static BOOL DIALOG_CreateControls( WND *pWnd, LPCSTR strTemplate, 349 const DLG_TEMPLATE *dlgTemplate, 350 HINSTANCE hInst, BOOL win32 ) 351 { 352 DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra; 353 DLG_CONTROL_INFO info; 354 HWND hwndCtrl, hwndDefButton = 0; 355 INT items = dlgTemplate->nbItems; 356 357 dprintf(("USER32: BEGIN\n" )); 358 while (items--) 359 { 360 { 361 strTemplate = (LPCSTR)DIALOG_GetControl32( (WORD *)strTemplate, &info, 362 dlgTemplate->dialogEx ); 363 hwndCtrl = CreateWindowExW( info.exStyle | WS_EX_NOPARENTNOTIFY, 364 (LPCWSTR)info.className, 365 (LPCWSTR)info.windowName, 366 info.style | WS_CHILD, 367 info.x * dlgInfo->xBaseUnit / 4, 368 info.y * dlgInfo->yBaseUnit / 8, 369 info.cx * dlgInfo->xBaseUnit / 4, 370 info.cy * dlgInfo->yBaseUnit / 8, 371 pWnd->hwndSelf, (HMENU)info.id, 372 hInst, info.data ); 373 } 374 if (!hwndCtrl) return FALSE; 375 376 /* Send initialisation messages to the control */ 377 if (dlgInfo->hUserFont) SendMessageA( hwndCtrl, WM_SETFONT, 378 (WPARAM)dlgInfo->hUserFont, 0 ); 379 if (SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) 380 { 381 /* If there's already a default push-button, set it back */ 382 /* to normal and use this one instead. */ 383 if (hwndDefButton) 384 SendMessageA( hwndDefButton, BM_SETSTYLE, 385 BS_PUSHBUTTON,FALSE ); 386 hwndDefButton = hwndCtrl; 387 dlgInfo->idResult = GetWindowWord( hwndCtrl, GWW_ID ); 388 } 389 } 390 dprintf(("USER32: END\n" )); 391 return TRUE; 392 } 393 394 395 /*********************************************************************** 396 * DIALOG_ParseTemplate32 397 * 398 * Fill a DLG_TEMPLATE structure from the dialog template, and return 399 * a pointer to the first control. 400 */ 401 static LPCSTR DIALOG_ParseTemplate32( LPCSTR strTemplate, DLG_TEMPLATE * result ) 402 { 403 const WORD *p = (const WORD *)strTemplate; 404 405 result->style = GET_DWORD(p); p += 2; 406 if (result->style == 0xffff0001) /* DIALOGEX resource */ 407 { 408 result->dialogEx = TRUE; 409 result->helpId = GET_DWORD(p); p += 2; 410 result->exStyle = GET_DWORD(p); p += 2; 411 result->style = GET_DWORD(p); p += 2; 412 } 413 else 414 { 415 result->dialogEx = FALSE; 416 result->helpId = 0; 417 result->exStyle = GET_DWORD(p); p += 2; 418 } 419 result->nbItems = GET_WORD(p); p++; 420 result->x = GET_WORD(p); p++; 421 result->y = GET_WORD(p); p++; 422 result->cx = GET_WORD(p); p++; 423 result->cy = GET_WORD(p); p++; 424 dprintf(("USER32:DIALOG%s %d, %d, %d, %d, %ld\n", 425 result->dialogEx ? "EX" : "", result->x, result->y, 426 result->cx, result->cy, result->helpId )); 427 dprintf(("USER32: STYLE 0x%08lx\n", result->style )); 428 dprintf(("USER32: EXSTYLE 0x%08lx\n", result->exStyle )); 429 430 /* Get the menu name */ 431 432 switch(GET_WORD(p)) 433 { 434 case 0x0000: 435 result->menuName = NULL; 436 p++; 437 break; 438 case 0xffff: 439 result->menuName = (LPCSTR)(UINT)GET_WORD( p + 1 ); 440 p += 2; 441 dprintf(("USER32: MENU %04x\n", LOWORD(result->menuName) )); 442 break; 443 default: 444 result->menuName = (LPCSTR)p; 445 dprintf(("USER32: MENU %ls\n", (LPCWSTR)p )); 446 p += lstrlenW( (LPCWSTR)p ) + 1; 447 break; 448 } 449 450 /* Get the class name */ 451 452 switch(GET_WORD(p)) 453 { 454 case 0x0000: 455 result->className = DIALOG_CLASS_ATOM; 456 p++; 457 break; 458 case 0xffff: 459 result->className = (LPCSTR)(UINT)GET_WORD( p + 1 ); 460 p += 2; 461 dprintf(("USER32: CLASS %04x\n", LOWORD(result->className) )); 462 break; 463 default: 464 result->className = (LPCSTR)p; 465 dprintf(("USER32: CLASS %ls\n", (LPCWSTR)p )); 466 p += lstrlenW( (LPCWSTR)p ) + 1; 467 break; 468 } 469 470 /* Get the window caption */ 471 472 result->caption = (LPCSTR)p; 473 p += lstrlenW( (LPCWSTR)p ) + 1; 474 dprintf(("USER32: CAPTION %ls\n", (LPCWSTR)result->caption )); 475 476 /* Get the font name */ 477 478 if (result->style & DS_SETFONT) 479 { 480 result->pointSize = GET_WORD(p); 481 p++; 482 if (result->dialogEx) 483 { 484 result->weight = GET_WORD(p); p++; 485 result->italic = LOBYTE(GET_WORD(p)); p++; 486 } 487 else 488 { 489 result->weight = FW_DONTCARE; 490 result->italic = FALSE; 491 } 492 result->faceName = (LPCSTR)p; 493 p += lstrlenW( (LPCWSTR)p ) + 1; 494 dprintf(("USER32: FONT %d, %ls, %d, %s\n", 495 result->pointSize, (LPCWSTR)result->faceName, 496 result->weight, result->italic ? "TRUE" : "FALSE" )); 497 } 498 499 /* First control is on dword boundary */ 500 return (LPCSTR)((((int)p) + 3) & ~3); 501 } 502 503 504 /*********************************************************************** 505 * DIALOG_CreateIndirect 506 */ 507 HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, 508 BOOL win32Template, HWND owner, 509 DLGPROC16 dlgProc, LPARAM param, 510 WINDOWPROCTYPE procType ) 511 { 512 HMENU16 hMenu = 0; 513 HFONT16 hFont = 0; 514 HWND hwnd; 515 RECT rect; 516 WND * wndPtr; 517 DLG_TEMPLATE strTemplate; 518 DIALOGINFO * dlgInfo; 519 WORD xUnit = xBaseUnit; 520 WORD yUnit = yBaseUnit; 521 522 /* Parse dialog template */ 523 524 if (!dlgTemplate) return 0; 525 dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &strTemplate ); 526 527 /* Load menu */ 528 529 if (strTemplate.menuName) 530 hMenu = LoadMenuW( hInst, (LPCWSTR)strTemplate.menuName ); 531 532 /* Create custom font if needed */ 533 534 if (strTemplate.style & DS_SETFONT) 535 { 536 /* The font height must be negative as it is a point size */ 537 /* (see CreateFont() documentation in the Windows SDK). */ 538 539 if (win32Template) 540 hFont = CreateFontW( -strTemplate.pointSize, 0, 0, 0, 541 strTemplate.weight, strTemplate.italic, FALSE, 542 FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY, 543 FF_DONTCARE, (LPCWSTR)strTemplate.faceName ); 544 else 545 hFont = CreateFont16( -strTemplate.pointSize, 0, 0, 0, FW_DONTCARE, 546 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, 547 PROOF_QUALITY, FF_DONTCARE, 548 strTemplate.faceName ); 549 if (hFont) 550 { 551 SIZE charSize; 552 DIALOG_GetCharSize(hFont,&charSize); 553 xUnit = charSize.cx; 554 yUnit = charSize.cy; 555 } 556 } 557 558 /* Create dialog main window */ 559 560 rect.left = rect.top = 0; 561 rect.right = strTemplate.cx * xUnit / 4; 562 rect.bottom = strTemplate.cy * yUnit / 8; 563 if (strTemplate.style & DS_MODALFRAME) 564 strTemplate.exStyle |= WS_EX_DLGMODALFRAME; 565 AdjustWindowRectEx( &rect, strTemplate.style, 566 hMenu ? TRUE : FALSE , strTemplate.exStyle ); 567 rect.right -= rect.left; 568 rect.bottom -= rect.top; 569 570 if ((INT16)strTemplate.x == CW_USEDEFAULT16) 571 { 572 rect.left = rect.top = win32Template? CW_USEDEFAULT : CW_USEDEFAULT16; 573 } 574 else 575 { 576 if (strTemplate.style & DS_CENTER) 577 { 578 rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2; 579 rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2; 580 } 581 else 582 { 583 rect.left += strTemplate.x * xUnit / 4; 584 rect.top += strTemplate.y * yUnit / 8; 585 } 586 if ( !(strTemplate.style & WS_CHILD) ) 587 { 588 INT16 dX, dY; 589 590 if( !(strTemplate.style & DS_ABSALIGN) ) 591 ClientToScreen( owner, (POINT *)&rect ); 592 593 /* try to fit it into the desktop */ 594 595 if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME) 596 - GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX; 597 if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME) 598 - GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY; 599 if( rect.left < 0 ) rect.left = 0; 600 if( rect.top < 0 ) rect.top = 0; 601 } 602 } 603 604 hwnd = CreateWindowExW(strTemplate.exStyle, (LPCWSTR)strTemplate.className, 605 (LPCWSTR)strTemplate.caption, 606 strTemplate.style & ~WS_VISIBLE, 607 rect.left, rect.top, rect.right, rect.bottom, 608 owner, hMenu, hInst, NULL ); 609 610 if (!hwnd) 611 { 612 if (hFont) DeleteObject( hFont ); 613 if (hMenu) DestroyMenu( hMenu ); 614 return 0; 615 } 616 wndPtr = WIN_FindWndPtr( hwnd ); 617 wndPtr->flags |= WIN_ISDIALOG; 618 wndPtr->helpContext = strTemplate.helpId; 619 620 /* Initialise dialog extra data */ 621 622 dlgInfo = (DIALOGINFO *)wndPtr->wExtra; 623 WINPROC_SetProc( &dlgInfo->dlgProc, (WNDPROC16)dlgProc, procType, WIN_PROC_WINDOW ); 624 dlgInfo->hUserFont = hFont; 625 dlgInfo->hMenu = hMenu; 626 dlgInfo->xBaseUnit = xUnit; 627 dlgInfo->yBaseUnit = yUnit; 628 dlgInfo->msgResult = 0; 629 dlgInfo->idResult = 0; 630 dlgInfo->flags = 0; 631 dlgInfo->hDialogHeap = 0; 632 633 if (dlgInfo->hUserFont) 634 SendMessageA( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 ); 635 636 /* Create controls */ 637 638 if (DIALOG_CreateControls( wndPtr, dlgTemplate, &strTemplate, 639 hInst, win32Template )) 640 { 641 /* Send initialisation messages and set focus */ 642 643 dlgInfo->hwndFocus = GetNextDlgTabItem( hwnd, 0, FALSE ); 644 645 if (SendMessageA( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param )) 646 SetFocus( dlgInfo->hwndFocus ); 647 648 if (strTemplate.style & WS_VISIBLE && !(wndPtr->dwStyle & WS_VISIBLE)) 649 { 650 ShowWindow( hwnd, SW_SHOWNORMAL ); /* SW_SHOW doesn't always work */ 651 UpdateWindow( hwnd ); 652 } 653 WIN_ReleaseWndPtr(wndPtr); 654 return hwnd; 655 } 656 WIN_ReleaseWndPtr(wndPtr); 657 if( IsWindow(hwnd) ) DestroyWindow( hwnd ); 658 return 0; 659 } 660 661 662 /*********************************************************************** 663 * CreateDialogParam32A (USER32.73) 664 */ 665 HWND WINAPI CreateDialogParamA( HINSTANCE hInst, LPCSTR name, 666 HWND owner, DLGPROC dlgProc, 667 LPARAM param ) 668 { 669 HANDLE hrsrc = FindResourceA( hInst, name, RT_DIALOGA ); 670 if (!hrsrc) return 0; 671 return CreateDialogIndirectParamA( hInst, 672 (DLGTEMPLATE*)LoadResource(hInst, hrsrc), 673 owner, dlgProc, param ); 674 } 675 676 677 /*********************************************************************** 678 * CreateDialogParam32W (USER32.74) 679 */ 680 HWND WINAPI CreateDialogParamW( HINSTANCE hInst, LPCWSTR name, 681 HWND owner, DLGPROC dlgProc, 682 LPARAM param ) 683 { 684 HANDLE hrsrc = FindResourceW( hInst, name, RT_DIALOGW ); 685 if (!hrsrc) return 0; 686 return CreateDialogIndirectParamW( hInst, 687 (DLGTEMPLATE*)LoadResource(hInst, hrsrc), 688 owner, dlgProc, param ); 689 } 690 691 692 /*********************************************************************** 693 * CreateDialogIndirectParam32A (USER32.69) 694 */ 695 HWND WINAPI CreateDialogIndirectParamA( HINSTANCE hInst, 696 LPCVOID dlgTemplate, 697 HWND owner, DLGPROC dlgProc, 698 LPARAM param ) 699 { 700 return DIALOG_CreateIndirect( hInst, (LPCSTR)dlgTemplate, TRUE, owner, 701 (DLGPROC16)dlgProc, param, WIN_PROC_32A ); 702 } 703 704 /*********************************************************************** 705 * CreateDialogIndirectParam32AorW (USER32.71) 706 */ 707 HWND WINAPI CreateDialogIndirectParamAorW( HINSTANCE hInst, 708 LPCVOID dlgTemplate, 709 HWND owner, DLGPROC dlgProc, 710 LPARAM param ) 711 { 712 dprintf(("USER32- FIXME-assume WIN_PROC_32W\n")); 713 return DIALOG_CreateIndirect( hInst, (LPCSTR)dlgTemplate, TRUE, owner, 714 (DLGPROC16)dlgProc, param, WIN_PROC_32W ); 715 } 716 717 /*********************************************************************** 718 * CreateDialogIndirectParam32W (USER32.72) 719 */ 720 HWND WINAPI CreateDialogIndirectParamW( HINSTANCE hInst, 721 LPCVOID dlgTemplate, 722 HWND owner, DLGPROC dlgProc, 723 LPARAM param ) 724 { 725 return DIALOG_CreateIndirect( hInst, (LPCSTR)dlgTemplate, TRUE, owner, 726 (DLGPROC16)dlgProc, param, WIN_PROC_32W ); 727 } 728 729 730 /*********************************************************************** 731 * DIALOG_DoDialogBox 732 */ 733 INT DIALOG_DoDialogBox( HWND hwnd, HWND owner ) 734 { 735 WND * wndPtr; 736 DIALOGINFO * dlgInfo; 737 MSG msg; 738 INT retval; 739 740 /* Owner must be a top-level window */ 741 owner = WIN_GetTopParent( owner ); 742 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1; 743 dlgInfo = (DIALOGINFO *)wndPtr->wExtra; 744 745 if (!dlgInfo->flags & DF_END) /* was EndDialog called in WM_INITDIALOG ? */ 746 { 747 EnableWindow( owner, FALSE ); 748 ShowWindow( hwnd, SW_SHOW ); 749 while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, 750 PM_REMOVE, !(wndPtr->dwStyle & DS_NOIDLEMSG), NULL )) 751 { 752 if (!IsDialogMessageA( hwnd, &msg)) 753 { 754 TranslateMessage( &msg ); 755 DispatchMessageA( &msg ); 756 } 757 if (dlgInfo->flags & DF_END) break; 758 } 759 EnableWindow( owner, TRUE ); 760 } 761 retval = dlgInfo->idResult; 762 WIN_ReleaseWndPtr(wndPtr); 763 DestroyWindow( hwnd ); 764 return retval; 765 } 766 767 768 /*********************************************************************** 769 * DialogBoxParam32A (USER32.139) 770 */ 771 INT WINAPI DialogBoxParamA( HINSTANCE hInst, LPCSTR name, 772 HWND owner, DLGPROC dlgProc, LPARAM param ) 773 { 774 HWND hwnd = CreateDialogParamA( hInst, name, owner, dlgProc, param ); 775 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); 776 return -1; 777 } 778 779 780 /*********************************************************************** 781 * DialogBoxParam32W (USER32.140) 782 */ 783 INT WINAPI DialogBoxParamW( HINSTANCE hInst, LPCWSTR name, 784 HWND owner, DLGPROC dlgProc, LPARAM param ) 785 { 786 HWND hwnd = CreateDialogParamW( hInst, name, owner, dlgProc, param ); 787 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); 788 return -1; 789 } 790 791 792 /*********************************************************************** 793 * DialogBoxIndirectParam32A (USER32.136) 794 */ 795 INT WINAPI DialogBoxIndirectParamA(HINSTANCE hInstance, LPCVOID strTemplate, 796 HWND owner, DLGPROC dlgProc, 797 LPARAM param ) 798 { 799 HWND hwnd = CreateDialogIndirectParamA( hInstance, strTemplate, 800 owner, dlgProc, param ); 801 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); 802 return -1; 803 } 804 805 806 /*********************************************************************** 807 * DialogBoxIndirectParam32W (USER32.138) 808 */ 809 INT WINAPI DialogBoxIndirectParamW(HINSTANCE hInstance, LPCVOID strTemplate, 810 HWND owner, DLGPROC dlgProc, 811 LPARAM param ) 812 { 813 HWND hwnd = CreateDialogIndirectParamW( hInstance, strTemplate, 814 owner, dlgProc, param ); 815 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); 816 return -1; 817 } 818 819 820 /*********************************************************************** 821 * EndDialog32 (USER32.173) 822 */ 823 BOOL WINAPI EndDialog( HWND hwnd, INT retval ) 824 { 825 WND * wndPtr = WIN_FindWndPtr( hwnd ); 826 DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra; 827 828 dprintf(("USER32:%04x %d\n", hwnd, retval )); 829 830 if( dlgInfo ) 831 { 832 dlgInfo->idResult = retval; 833 dlgInfo->flags |= DF_END; 834 } 835 836 /* Windows sets the focus to the dialog itself first in EndDialog */ 837 838 if (IsChild(hwnd, GetFocus())) 839 SetFocus(wndPtr->hwndSelf); 840 841 /* Paint Shop Pro 4.14 calls EndDialog for a CreateDialog* dialog, 842 * which isn't "normal". Only DialogBox* dialogs may be EndDialog()ed. 843 * Just hide the window 844 * and re-enable the owner as windows does it... 845 */ 846 ShowWindow(hwnd, SW_HIDE); 847 848 if(wndPtr->owner) 849 { 850 HWND hOwner; 851 /* Owner must be a top-level window */ 852 hOwner = WIN_GetTopParent( wndPtr->owner->hwndSelf ); 853 EnableWindow( hOwner, TRUE ); 854 } 855 856 WIN_ReleaseWndPtr(wndPtr); 857 858 return TRUE; 859 } 860 861 862 /*********************************************************************** 863 * DIALOG_IsAccelerator 864 */ 865 static BOOL DIALOG_IsAccelerator( HWND hwnd, HWND hwndDlg, WPARAM vKey ) 866 { 867 HWND hwndControl = hwnd; 868 HWND hwndNext; 869 WND *wndPtr; 870 BOOL RetVal = FALSE; 871 INT dlgCode; 872 873 if (vKey == VK_SPACE) 874 { 875 dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 ); 876 if (dlgCode & DLGC_BUTTON) 877 { 878 SendMessageA( hwndControl, WM_LBUTTONDOWN, 0, 0); 879 SendMessageA( hwndControl, WM_LBUTTONUP, 0, 0); 880 RetVal = TRUE; 881 } 882 } 883 else 884 { 885 do 886 { 887 wndPtr = WIN_FindWndPtr( hwndControl ); 888 if ( (wndPtr != NULL) && 889 ((wndPtr->dwStyle & (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE) ) 890 { 891 dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 ); 892 if ( (dlgCode & (DLGC_BUTTON | DLGC_STATIC)) && 893 (wndPtr->text!=NULL)) 894 { 895 /* find the accelerator key */ 896 LPSTR p = wndPtr->text - 2; 897 do 898 { 899 p = strchr( p + 2, '&' ); 900 } 901 while (p != NULL && p[1] == '&'); 902 903 /* and check if it's the one we're looking for */ 904 if (p != NULL && toupper( p[1] ) == toupper( vKey ) ) 905 { 906 if ((dlgCode & DLGC_STATIC) || 907 (wndPtr->dwStyle & 0x0f) == BS_GROUPBOX ) 908 { 909 /* set focus to the control */ 910 SendMessageA( hwndDlg, WM_NEXTDLGCTL, 911 hwndControl, 1); 912 /* and bump it on to next */ 913 SendMessageA( hwndDlg, WM_NEXTDLGCTL, 0, 0); 914 } 915 else if (dlgCode & 916 (DLGC_DEFPUSHBUTTON | DLGC_UNDEFPUSHBUTTON)) 917 { 918 /* send command message as from the control */ 919 SendMessageA( hwndDlg, WM_COMMAND, 920 MAKEWPARAM( LOWORD(wndPtr->wIDmenu), 921 BN_CLICKED ), 922 (LPARAM)hwndControl ); 923 } 924 else 925 { 926 /* click the control */ 927 SendMessageA( hwndControl, WM_LBUTTONDOWN, 0, 0); 928 SendMessageA( hwndControl, WM_LBUTTONUP, 0, 0); 929 } 930 RetVal = TRUE; 931 WIN_ReleaseWndPtr(wndPtr); 932 break; 933 } 934 } 935 hwndNext = GetWindow( hwndControl, GW_CHILD ); 936 } 937 else 938 { 939 hwndNext = 0; 940 } 941 WIN_ReleaseWndPtr(wndPtr); 942 if (!hwndNext) 943 { 944 hwndNext = GetWindow( hwndControl, GW_HWNDNEXT ); 945 } 946 while (!hwndNext) 947 { 948 hwndControl = GetParent( hwndControl ); 949 if (hwndControl == hwndDlg) 950 { 951 if(hwnd==hwndDlg){ /* prevent endless loop */ 952 hwndNext=hwnd; 953 break; 954 } 955 hwndNext = GetWindow( hwndDlg, GW_CHILD ); 956 } 957 else 958 { 959 hwndNext = GetWindow( hwndControl, GW_HWNDNEXT ); 960 } 961 } 962 hwndControl = hwndNext; 963 } 964 while (hwndControl != hwnd); 965 } 966 return RetVal; 967 } 968 969 970 /*********************************************************************** 971 * DIALOG_IsDialogMessage 972 */ 973 static BOOL DIALOG_IsDialogMessage( HWND hwnd, HWND hwndDlg, 974 UINT message, WPARAM wParam, 975 LPARAM lParam, BOOL *translate, 976 BOOL *dispatch, INT dlgCode ) 977 { 978 *translate = *dispatch = FALSE; 979 980 if (message == WM_PAINT) 981 { 982 /* Apparently, we have to handle this one as well */ 983 *dispatch = TRUE; 984 return TRUE; 985 } 986 987 /* Only the key messages get special processing */ 988 if ((message != WM_KEYDOWN) && 989 (message != WM_SYSCHAR) && 990 (message != WM_CHAR)) 991 return FALSE; 992 993 if (dlgCode & DLGC_WANTMESSAGE) 994 { 995 *translate = *dispatch = TRUE; 996 return TRUE; 997 } 998 999 switch(message) 1000 { 1001 case WM_KEYDOWN: 1002 switch(wParam) 1003 { 1004 case VK_TAB: 1005 if (!(dlgCode & DLGC_WANTTAB)) 1006 { 1007 SendMessageA( hwndDlg, WM_NEXTDLGCTL, 1008 (GetKeyState(VK_SHIFT) & 0x8000), 0 ); 1009 return TRUE; 1010 } 1011 break; 1012 1013 case VK_RIGHT: 1014 case VK_DOWN: 1015 case VK_LEFT: 1016 case VK_UP: 1017 if (!(dlgCode & DLGC_WANTARROWS)) 1018 { 1019 BOOL fPrevious = (wParam == VK_LEFT || wParam == VK_UP); 1020 HWND hwndNext = 1021 GetNextDlgGroupItem (hwndDlg, GetFocus(), fPrevious ); 1022 SendMessageA( hwndDlg, WM_NEXTDLGCTL, hwndNext, 1 ); 1023 return TRUE; 1024 } 1025 break; 1026 1027 case VK_ESCAPE: 1028 SendMessageA( hwndDlg, WM_COMMAND, IDCANCEL, 1029 (LPARAM)GetDlgItem( hwndDlg, IDCANCEL ) ); 1030 return TRUE; 1031 1032 case VK_RETURN: 1033 { 1034 DWORD dw = SendMessageA( hwndDlg, DM_GETDEFID, 0, 0 ); 1035 if (HIWORD(dw) == DC_HASDEFID) 1036 { 1037 SendMessageA( hwndDlg, WM_COMMAND, 1038 MAKEWPARAM( LOWORD(dw), BN_CLICKED ), 1039 (LPARAM)GetDlgItem(hwndDlg, LOWORD(dw))); 1040 } 1041 else 1042 { 1043 SendMessageA( hwndDlg, WM_COMMAND, IDOK, 1044 (LPARAM)GetDlgItem( hwndDlg, IDOK ) ); 1045 1046 } 1047 } 1048 return TRUE; 1049 } 1050 *translate = TRUE; 1051 break; /* case WM_KEYDOWN */ 1052 1053 case WM_CHAR: 1054 if (dlgCode & DLGC_WANTCHARS) break; 1055 /* drop through */ 1056 1057 case WM_SYSCHAR: 1058 if (DIALOG_IsAccelerator( hwnd, hwndDlg, wParam )) 1059 { 1060 /* don't translate or dispatch */ 1061 return TRUE; 1062 } 1063 break; 1064 } 1065 1066 /* If we get here, the message has not been treated specially */ 1067 /* and can be sent to its destination window. */ 1068 *dispatch = TRUE; 1069 return TRUE; 1070 } 1071 1072 1073 /*********************************************************************** 1074 * IsDialogMessage32A (USER32.342) 1075 */ 1076 BOOL WINAPI IsDialogMessageA( HWND hwndDlg, LPMSG msg ) 1077 { 1078 BOOL ret, translate, dispatch; 1079 INT dlgCode; 1080 1081 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) 1082 return FALSE; 1083 1084 dlgCode = SendMessageA( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg); 1085 ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, 1086 msg->wParam, msg->lParam, 1087 &translate, &dispatch, dlgCode ); 1088 if (translate) TranslateMessage( msg ); 1089 if (dispatch) DispatchMessageA( msg ); 1090 return ret; 1091 } 1092 1093 1094 /*********************************************************************** 1095 * IsDialogMessage32W (USER32.343) 1096 */ 1097 BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg ) 1098 { 1099 BOOL ret, translate, dispatch; 1100 INT dlgCode; 1101 1102 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) 1103 return FALSE; 1104 1105 dlgCode = SendMessageW( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg); 1106 ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, 1107 msg->wParam, msg->lParam, 1108 &translate, &dispatch, dlgCode ); 1109 if (translate) TranslateMessage( msg ); 1110 if (dispatch) DispatchMessageW( msg ); 1111 return ret; 1112 } 1113 1114 1115 /**************************************************************** 1116 * GetDlgCtrlID32 (USER32.234) 1117 */ 1118 INT WINAPI GetDlgCtrlID( HWND hwnd ) 1119 { 1120 INT retvalue; 1121 WND *wndPtr = WIN_FindWndPtr(hwnd); 1122 if (!wndPtr) return 0; 1123 retvalue = wndPtr->wIDmenu; 1124 WIN_ReleaseWndPtr(wndPtr); 1125 return retvalue; 1126 } 1127 1128 1129 /*********************************************************************** 1130 * GetDlgItem32 (USER32.235) 1131 */ 1132 HWND WINAPI GetDlgItem( HWND hwndDlg, INT id ) 1133 { 1134 WND *pWnd; 1135 1136 if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0; 1137 for (WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next)) 1138 if (pWnd->wIDmenu == (UINT16)id) 1139 { 1140 HWND retvalue = pWnd->hwndSelf; 1141 WIN_ReleaseWndPtr(pWnd); 1142 return retvalue; 1143 } 1144 return 0; 1145 } 1146 1147 1148 /******************************************************************* 1149 * SendDlgItemMessage32A (USER32.452) 1150 */ 1151 LRESULT WINAPI SendDlgItemMessageA( HWND hwnd, INT id, UINT msg, 1152 WPARAM wParam, LPARAM lParam ) 1153 { 1154 HWND hwndCtrl = GetDlgItem( hwnd, id ); 1155 if (hwndCtrl) return SendMessageA( hwndCtrl, msg, wParam, lParam ); 1156 else return 0; 1157 } 1158 1159 1160 /******************************************************************* 1161 * SendDlgItemMessage32W (USER32.453) 1162 */ 1163 LRESULT WINAPI SendDlgItemMessageW( HWND hwnd, INT id, UINT msg, 1164 WPARAM wParam, LPARAM lParam ) 1165 { 1166 HWND hwndCtrl = GetDlgItem( hwnd, id ); 1167 if (hwndCtrl) return SendMessageW( hwndCtrl, msg, wParam, lParam ); 1168 else return 0; 1169 } 1170 1171 1172 /******************************************************************* 1173 * SetDlgItemText32A (USER32.478) 1174 */ 1175 BOOL WINAPI SetDlgItemTextA( HWND hwnd, INT id, LPCSTR lpString ) 1176 { 1177 return SendDlgItemMessageA( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); 1178 } 1179 1180 1181 /******************************************************************* 1182 * SetDlgItemText32W (USER32.479) 1183 */ 1184 BOOL WINAPI SetDlgItemTextW( HWND hwnd, INT id, LPCWSTR lpString ) 1185 { 1186 return SendDlgItemMessageW( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); 1187 } 1188 1189 1190 /*********************************************************************** 1191 * GetDlgItemText32A (USER32.237) 1192 */ 1193 UINT WINAPI GetDlgItemTextA( HWND hwnd, INT id, LPSTR str, UINT len ) 1194 { 1195 return (UINT)SendDlgItemMessageA( hwnd, id, WM_GETTEXT, 1196 len, (LPARAM)str ); 1197 } 1198 1199 1200 /*********************************************************************** 1201 * GetDlgItemText32W (USER32.238) 1202 */ 1203 UINT WINAPI GetDlgItemTextW( HWND hwnd, INT id, LPWSTR str, UINT len ) 1204 { 1205 return (UINT)SendDlgItemMessageW( hwnd, id, WM_GETTEXT, 1206 len, (LPARAM)str ); 1207 } 1208 1209 1210 /******************************************************************* 1211 * SetDlgItemInt32 (USER32.477) 1212 */ 1213 BOOL WINAPI SetDlgItemInt( HWND hwnd, INT id, UINT value, 1214 BOOL fSigned ) 1215 { 1216 char str[20]; 1217 1218 if (fSigned) sprintf( str, "%d", (INT)value ); 1219 else sprintf( str, "%u", value ); 1220 SendDlgItemMessageA( hwnd, id, WM_SETTEXT, 0, (LPARAM)str ); 1221 return TRUE; 1222 } 1223 1224 1225 /*********************************************************************** 1226 * GetDlgItemInt32 (USER32.236) 1227 */ 1228 UINT WINAPI GetDlgItemInt( HWND hwnd, INT id, BOOL *translated, 1229 BOOL fSigned ) 1230 { 1231 char str[30]; 1232 char * endptr; 1233 long result = 0; 1234 1235 if (translated) *translated = FALSE; 1236 if (!SendDlgItemMessageA(hwnd, id, WM_GETTEXT, sizeof(str), (LPARAM)str)) 1237 return 0; 1238 if (fSigned) 1239 { 1240 result = strtol( str, &endptr, 10 ); 1241 if (!endptr || (endptr == str)) /* Conversion was unsuccessful */ 1242 return 0; 1243 if (((result == LONG_MIN) || (result == LONG_MAX)) && (errno==ERANGE)) 1244 return 0; 1245 } 1246 else 1247 { 1248 result = strtoul( str, &endptr, 10 ); 1249 if (!endptr || (endptr == str)) /* Conversion was unsuccessful */ 1250 return 0; 1251 if ((result == ULONG_MAX) && (errno == ERANGE)) return 0; 1252 } 1253 if (translated) *translated = TRUE; 1254 return (UINT)result; 1255 } 1256 1257 1258 /*********************************************************************** 1259 * CheckDlgButton32 (USER32.45) 1260 */ 1261 BOOL WINAPI CheckDlgButton( HWND hwnd, INT id, UINT check ) 1262 { 1263 SendDlgItemMessageA( hwnd, id, BM_SETCHECK, check, 0 ); 1264 return TRUE; 1265 } 1266 1267 1268 /*********************************************************************** 1269 * IsDlgButtonChecked32 (USER32.344) 1270 */ 1271 UINT WINAPI IsDlgButtonChecked( HWND hwnd, UINT id ) 1272 { 1273 return (UINT)SendDlgItemMessageA( hwnd, id, BM_GETCHECK, 0, 0 ); 1274 } 1275 1276 1277 /*********************************************************************** 1278 * CheckRB 1279 * 1280 * Callback function used to check/uncheck radio buttons that fall 1281 * within a specific range of IDs. 1282 */ 1283 static BOOL CALLBACK CheckRB(HWND hwndChild, LPARAM lParam) 1284 { 1285 LONG lChildID = GetWindowLongA(hwndChild, GWL_ID); 1286 RADIOGROUP *lpRadioGroup = (RADIOGROUP *) lParam; 1287 1288 if ((lChildID >= lpRadioGroup->firstID) && 1289 (lChildID <= lpRadioGroup->lastID)) 1290 { 1291 if (lChildID == lpRadioGroup->checkID) 1292 { 1293 SendMessageA(hwndChild, BM_SETCHECK, BST_CHECKED, 0); 1294 } 1295 else 1296 { 1297 SendMessageA(hwndChild, BM_SETCHECK, BST_UNCHECKED, 0); 1298 } 1299 } 1300 1301 return TRUE; 1302 } 1303 1304 1305 /*********************************************************************** 1306 * CheckRadioButton32 (USER32.48) 1307 */ 1308 BOOL WINAPI CheckRadioButton( HWND hwndDlg, UINT firstID, 1309 UINT lastID, UINT checkID ) 1310 { 1311 RADIOGROUP radioGroup; 1312 1313 /* perform bounds checking for a radio button group */ 1314 radioGroup.firstID = min(min(firstID, lastID), checkID); 1315 radioGroup.lastID = max(max(firstID, lastID), checkID); 1316 radioGroup.checkID = checkID; 1317 1318 return EnumChildWindows(hwndDlg, (WNDENUMPROC)CheckRB, 1319 (LPARAM)&radioGroup); 1320 } 1321 1322 1323 /*********************************************************************** 1324 * GetDialogBaseUnits (USER.243) (USER32.233) 1325 */ 1326 DWORD WINAPI GetDialogBaseUnits(void) 1327 { 1328 return MAKELONG( xBaseUnit, yBaseUnit ); 1329 } 1330 1331 1332 /*********************************************************************** 1333 * MapDialogRect32 (USER32.382) 1334 */ 1335 BOOL WINAPI MapDialogRect( HWND hwnd, LPRECT rect ) 1336 { 1337 DIALOGINFO * dlgInfo; 1338 WND * wndPtr = WIN_FindWndPtr( hwnd ); 1339 if (!wndPtr) return FALSE; 1340 dlgInfo = (DIALOGINFO *)wndPtr->wExtra; 1341 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4; 1342 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4; 1343 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8; 1344 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8; 1345 WIN_ReleaseWndPtr(wndPtr); 1346 return TRUE; 1347 } 1348 1349 1350 /*********************************************************************** 1351 * GetNextDlgGroupItem32 (USER32.275) 1352 */ 1353 HWND WINAPI GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, 1354 BOOL fPrevious ) 1355 { 1356 WND *pWnd = NULL, 1357 *pWndLast = NULL, 1358 *pWndCtrl = NULL, 1359 *pWndDlg = NULL; 1360 HWND retvalue; 1361 1362 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; 1363 if (hwndCtrl) 1364 { 1365 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) 1366 { 1367 retvalue = 0; 1368 goto END; 1369 } 1370 /* Make sure hwndCtrl is a top-level child */ 1371 while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg)) 1372 WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->parent); 1373 if (pWndCtrl->parent != pWndDlg) 1374 { 1375 retvalue = 0; 1376 goto END; 1377 } 1378 } 1379 else 1380 { 1381 /* No ctrl specified -> start from the beginning */ 1382 if (!(pWndCtrl = WIN_LockWndPtr(pWndDlg->child))) 1383 { 1384 retvalue = 0; 1385 goto END; 1386 } 1387 if (fPrevious) 1388 while (pWndCtrl->next) WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->next); 1389 } 1390 1391 pWndLast = WIN_LockWndPtr(pWndCtrl); 1392 pWnd = WIN_LockWndPtr(pWndCtrl->next); 1393 1394 while (1) 1395 { 1396 if (!pWnd || (pWnd->dwStyle & WS_GROUP)) 1397 { 1398 /* Wrap-around to the beginning of the group */ 1399 WND *pWndTemp; 1400 1401 WIN_UpdateWndPtr( &pWnd, pWndDlg->child ); 1402 for ( pWndTemp = WIN_LockWndPtr( pWnd ); 1403 pWndTemp; 1404 WIN_UpdateWndPtr( &pWndTemp, pWndTemp->next) ) 1405 { 1406 if (pWndTemp->dwStyle & WS_GROUP) WIN_UpdateWndPtr( &pWnd, pWndTemp ); 1407 if (pWndTemp == pWndCtrl) break; 1408 } 1409 WIN_ReleaseWndPtr( pWndTemp ); 1410 } 1411 if (pWnd == pWndCtrl) break; 1412 if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED)) 1413 { 1414 WIN_UpdateWndPtr(&pWndLast,pWnd); 1415 if (!fPrevious) break; 1416 } 1417 WIN_UpdateWndPtr(&pWnd,pWnd->next); 1418 } 1419 retvalue = pWndLast->hwndSelf; 1420 1421 WIN_ReleaseWndPtr(pWndLast); 1422 WIN_ReleaseWndPtr(pWnd); 1423 END: 1424 WIN_ReleaseWndPtr(pWndCtrl); 1425 WIN_ReleaseWndPtr(pWndDlg); 1426 1427 return retvalue; 1428 } 1429 1430 1431 /*********************************************************************** 1432 * GetNextDlgTabItem32 (USER32.276) 1433 */ 1434 HWND WINAPI GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl, 1435 BOOL fPrevious ) 1436 { 1437 WND *pWnd = NULL, 1438 *pWndLast = NULL, 1439 *pWndCtrl = NULL, 1440 *pWndDlg = NULL; 1441 HWND retvalue; 1442 1443 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; 1444 if (hwndCtrl) 1445 { 1446 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) 1447 { 1448 retvalue = 0; 1449 goto END; 1450 } 1451 /* Make sure hwndCtrl is a top-level child */ 1452 while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg)) 1453 WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->parent); 1454 if (pWndCtrl->parent != pWndDlg) 1455 { 1456 retvalue = 0; 1457 goto END; 1458 } 1459 } 1460 else 1461 { 1462 /* No ctrl specified -> start from the beginning */ 1463 if (!(pWndCtrl = WIN_LockWndPtr(pWndDlg->child))) 1464 { 1465 retvalue = 0; 1466 goto END; 1467 } 1468 1469 if (!fPrevious) 1470 while (pWndCtrl->next) WIN_UpdateWndPtr(&pWndCtrl,pWndCtrl->next); 1471 } 1472 1473 pWndLast = WIN_LockWndPtr(pWndCtrl); 1474 pWnd = WIN_LockWndPtr(pWndCtrl->next); 1475 while (1) 1476 { 1477 if (!pWnd) pWnd = WIN_LockWndPtr(pWndDlg->child); 1478 if (pWnd == pWndCtrl) break; 1479 if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE) && 1480 !(pWnd->dwStyle & WS_DISABLED)) 1481 { 1482 WIN_UpdateWndPtr(&pWndLast,pWnd); 1483 if (!fPrevious) break; 1484 } 1485 WIN_UpdateWndPtr(&pWnd,pWnd->next); 1486 } 1487 retvalue = pWndLast->hwndSelf; 1488 1489 WIN_ReleaseWndPtr(pWndLast); 1490 WIN_ReleaseWndPtr(pWnd); 1491 END: 1492 WIN_ReleaseWndPtr(pWndCtrl); 1493 WIN_ReleaseWndPtr(pWndDlg); 1494 1495 return retvalue; 1496 1497 } 1498 1499 1500 /********************************************************************** 1501 * DIALOG_DlgDirSelect 1502 * 1503 * Helper function for DlgDirSelect* 1504 */ 1505 static BOOL DIALOG_DlgDirSelect( HWND hwnd, LPSTR str, INT len, 1506 INT id, BOOL unicode, 1507 BOOL combo ) 1508 { 1509 char *buffer, *ptr; 1510 INT item, size; 1511 BOOL ret; 1512 HWND listbox = GetDlgItem( hwnd, id ); 1513 1514 dprintf(("USER32:%04x '%s' %d\n", hwnd, str, id )); 1515 if (!listbox) return FALSE; 1516 1517 item = SendMessageA(listbox, combo ? CB_GETCURSEL 1518 : LB_GETCURSEL, 0, 0 ); 1519 if (item == LB_ERR) return FALSE; 1520 size = SendMessageA(listbox, combo ? CB_GETLBTEXTLEN 1521 : LB_GETTEXTLEN, 0, 0 ); 1522 if (size == LB_ERR) return FALSE; 1523 1524 if (!(buffer = (char*)HEAP_malloc( size+1 ))) return FALSE; 1525 1526 SendMessageA( listbox, combo ? CB_GETLBTEXT : LB_GETTEXT, 1527 item, (LPARAM)buffer ); 1528 1529 if ((ret = (buffer[0] == '['))) /* drive or directory */ 1530 { 1531 if (buffer[1] == '-') /* drive */ 1532 { 1533 buffer[3] = ':'; 1534 buffer[4] = 0; 1535 ptr = buffer + 2; 1536 } 1537 else 1538 { 1539 buffer[strlen(buffer)-1] = '\\'; 1540 ptr = buffer + 1; 1541 } 1542 } 1543 else ptr = buffer; 1544 1545 if (unicode) lstrcpynAtoW( (LPWSTR)str, ptr, len ); 1546 else lstrcpynA( str, ptr, len ); 1547 HEAP_free( buffer ); 1548 dprintf(("USER32:Returning %d '%s'\n", ret, str )); 1549 return ret; 1550 } 1551 1552 1553 /********************************************************************** 1554 * DIALOG_DlgDirList 1555 * 1556 * Helper function for DlgDirList* 1557 */ 1558 static INT DIALOG_DlgDirList( HWND hDlg, LPSTR spec, INT idLBox, 1559 INT idStatic, UINT attrib, BOOL combo ) 1560 { 1561 int drive; 1562 HWND hwnd; 1563 LPSTR orig_spec = spec; 1564 1565 #define SENDMSG(msg,wparam,lparam) \ 1566 ((attrib & DDL_POSTMSGS) ? PostMessageA( hwnd, msg, wparam, lparam ) \ 1567 : SendMessageA( hwnd, msg, wparam, lparam )) 1568 1569 dprintf(("USER32:%04x '%s' %d %d %04x\n", 1570 hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib )); 1571 1572 if (spec && spec[0] && (spec[1] == ':')) 1573 { 1574 drive = toupper( spec[0] ) - 'A'; 1575 spec += 2; 1576 if (!DRIVE_SetCurrentDrive( drive )) return FALSE; 1577 } 1578 else drive = DRIVE_GetCurrentDrive(); 1579 1580 /* If the path exists and is a directory, chdir to it */ 1581 if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*"; 1582 else 1583 { 1584 char *p, *p2; 1585 p = spec; 1586 if ((p2 = strrchr( p, '\\' ))) p = p2; 1587 if ((p2 = strrchr( p, '/' ))) p = p2; 1588 if (p != spec) 1589 { 1590 char sep = *p; 1591 *p = 0; 1592 if (!DRIVE_Chdir( drive, spec )) 1593 { 1594 *p = sep; /* Restore the original spec */ 1595 return FALSE; 1596 } 1597 spec = p + 1; 1598 } 1599 } 1600 1601 dprintf(("USER32:path=%c:\\%s mask=%s\n", 1602 'A' + drive, DRIVE_GetDosCwd(drive), spec )); 1603 1604 if (idLBox && ((hwnd = GetDlgItem( hDlg, idLBox )) != 0)) 1605 { 1606 SENDMSG( combo ? CB_RESETCONTENT : LB_RESETCONTENT, 0, 0 ); 1607 if (attrib & DDL_DIRECTORY) 1608 { 1609 if (!(attrib & DDL_EXCLUSIVE)) 1610 { 1611 if (SENDMSG( combo ? CB_DIR : LB_DIR, 1612 attrib & ~(DDL_DIRECTORY | DDL_DRIVES), 1613 (LPARAM)spec ) == LB_ERR) 1614 return FALSE; 1615 } 1616 if (SENDMSG( combo ? CB_DIR : LB_DIR, 1617 (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE, 1618 (LPARAM)"*.*" ) == LB_ERR) 1619 return FALSE; 1620 } 1621 else 1622 { 1623 if (SENDMSG( combo ? CB_DIR : LB_DIR, attrib, 1624 (LPARAM)spec ) == LB_ERR) 1625 return FALSE; 1626 } 1627 } 1628 1629 if (idStatic && ((hwnd = GetDlgItem( hDlg, idStatic )) != 0)) 1630 { 1631 char temp[512]; 1632 int drive = DRIVE_GetCurrentDrive(); 1633 strcpy( temp, "A:\\" ); 1634 temp[0] += drive; 1635 lstrcpynA( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 ); 1636 CharLowerA( temp ); 1637 /* Can't use PostMessage() here, because the string is on the stack */ 1638 SetDlgItemTextA( hDlg, idStatic, temp ); 1639 } 1640 1641 if (orig_spec && (spec != orig_spec)) 1642 { 1643 /* Update the original file spec */ 1644 char *p = spec; 1645 while ((*orig_spec++ = *p++)); 1646 } 1647 1648 return TRUE; 1649 #undef SENDMSG 1650 } 1651 1652 1653 /********************************************************************** 1654 * DIALOG_DlgDirListW 1655 * 1656 * Helper function for DlgDirList*32W 1657 */ 1658 static INT DIALOG_DlgDirListW( HWND hDlg, LPWSTR spec, INT idLBox, 1659 INT idStatic, UINT attrib, BOOL combo ) 1660 { 1661 if (spec) 1662 { 1663 LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec ); 1664 INT ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic, 1665 attrib, combo ); 1666 lstrcpyAtoW( spec, specA ); 1667 HeapFree( GetProcessHeap(), 0, specA ); 1668 return ret; 1669 } 1670 return DIALOG_DlgDirList( hDlg, NULL, idLBox, idStatic, attrib, combo ); 1671 } 1672 1673 1674 1675 /********************************************************************** 1676 * DlgDirSelectEx32A (USER32.149) 1677 */ 1678 BOOL WINAPI DlgDirSelectExA( HWND hwnd, LPSTR str, INT len, INT id ) 1679 { 1680 return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, FALSE ); 1681 } 1682 1683 1684 /********************************************************************** 1685 * DlgDirSelectEx32W (USER32.150) 1686 */ 1687 BOOL WINAPI DlgDirSelectExW( HWND hwnd, LPWSTR str, INT len, INT id ) 1688 { 1689 return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, FALSE ); 1690 } 1691 1692 1693 /********************************************************************** 1694 * DlgDirSelectComboBoxEx32A (USER32.147) 1695 */ 1696 BOOL WINAPI DlgDirSelectComboBoxExA( HWND hwnd, LPSTR str, INT len, 1697 INT id ) 1698 { 1699 return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, TRUE ); 1700 } 1701 1702 1703 /********************************************************************** 1704 * DlgDirSelectComboBoxEx32W (USER32.148) 1705 */ 1706 BOOL WINAPI DlgDirSelectComboBoxExW( HWND hwnd, LPWSTR str, INT len, 1707 INT id) 1708 { 1709 return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, TRUE ); 1710 } 1711 1712 1713 /********************************************************************** 1714 * DlgDirList32A (USER32.143) 1715 */ 1716 INT WINAPI DlgDirListA( HWND hDlg, LPSTR spec, INT idLBox, 1717 INT idStatic, UINT attrib ) 1718 { 1719 return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE ); 1720 } 1721 1722 1723 /********************************************************************** 1724 * DlgDirList32W (USER32.146) 1725 */ 1726 INT WINAPI DlgDirListW( HWND hDlg, LPWSTR spec, INT idLBox, 1727 INT idStatic, UINT attrib ) 1728 { 1729 return DIALOG_DlgDirListW( hDlg, spec, idLBox, idStatic, attrib, FALSE ); 1730 } 1731 1732 1733 /********************************************************************** 1734 * DlgDirListComboBox32A (USER32.144) 1735 */ 1736 INT WINAPI DlgDirListComboBoxA( HWND hDlg, LPSTR spec, INT idCBox, 1737 INT idStatic, UINT attrib ) 1738 { 1739 return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE ); 1740 } 1741 1742 1743 /********************************************************************** 1744 * DlgDirListComboBox32W (USER32.145) 1745 */ 1746 INT WINAPI DlgDirListComboBoxW( HWND hDlg, LPWSTR spec, INT idCBox, 1747 INT idStatic, UINT attrib ) 1748 { 1749 return DIALOG_DlgDirListW( hDlg, spec, idCBox, idStatic, attrib, TRUE ); 1750 }
Note:
See TracChangeset
for help on using the changeset viewer.