00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <os2win.h>
00015 #include <windowsx.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <misc.h>
00019 #include <win32dlg.h>
00020 #include <win\winproc.h>
00021 #include "oslibmsg.h"
00022 #include "oslibwin.h"
00023 #include "win32wdesktop.h"
00024 #include "controls.h"
00025 #include "syscolor.h"
00026 #include "hook.h"
00027 #include <math.h>
00028 #include <unicode.h>
00029
00030 #define DBG_LOCALLOG DBG_win32dlg
00031 #include "dbglocal.h"
00032
00033 #define DEFAULT_DLGFONT "9.WarpSans"
00034
00035 #define GET_SHORT(ptr) (*(SHORT *)(ptr))
00036
00037
00038
00039 Win32Dialog::Win32Dialog(HINSTANCE hInst, LPCSTR dlgTemplate, HWND owner,
00040 DLGPROC dlgProc, LPARAM param, BOOL isUnicode)
00041 : Win32BaseWindow()
00042 {
00043 RECT rect;
00044 WORD style;
00045 ATOM classAtom;
00046
00047 this->isUnicode = isUnicode;
00048 hUserFont = 0;
00049 hMenu = 0;
00050 hwndFocus = 0;
00051 Win32DlgProc = 0;
00052 msgResult = 0;
00053 userDlgData = 0;
00054 idResult = 0;
00055 dialogFlags = 0;
00056 fDialogInit = FALSE;
00057 memset(&dlgInfo, 0, sizeof(dlgInfo));
00058
00059 dprintf(("********* CREATE DIALOG ************"));
00060 if(fInitialized == FALSE) {
00061 if(DIALOG_Init() == FALSE) {
00062 dprintf(("DIALOG_Init FAILED!"));
00063 DebugInt3();
00064 SetLastError(ERROR_GEN_FAILURE);
00065 return;
00066 }
00067 fInitialized = TRUE;
00068 }
00069 xUnit = xBaseUnit;
00070 yUnit = yBaseUnit;
00071
00072
00073 dlgTemplate = parseTemplate(dlgTemplate, &dlgInfo);
00074
00075
00076 if (dlgInfo.menuName)
00077 {
00078 hMenu = LoadMenuW( hInst, (LPCWSTR)dlgInfo.menuName );
00079 }
00080
00081
00082 if (dlgInfo.style & DS_SETFONT)
00083 {
00084
00085
00086
00087 int pixels;
00088 if (((short)dlgInfo.pointSize) < 0)
00089 pixels = -((short)dlgInfo.pointSize);
00090 else
00091 {
00092 HDC hdc = GetDC(0);
00093 pixels = dlgInfo.pointSize * GetDeviceCaps(hdc, LOGPIXELSY)/72;
00094 ReleaseDC(0, hdc);
00095 }
00096
00097 hUserFont = CreateFontW(-pixels, 0, 0, 0,
00098 dlgInfo.weight, dlgInfo.italic, FALSE,
00099 FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY,
00100 FF_DONTCARE, (LPCWSTR)dlgInfo.faceName );
00101 if (hUserFont)
00102 {
00103 SIZE charSize;
00104 getCharSize(hUserFont,&charSize);
00105 xUnit = charSize.cx;
00106 yUnit = charSize.cy;
00107 }
00108 }
00109
00110
00111 setWindowContextHelpId(dlgInfo.helpId);
00112
00113
00114 rect.left = rect.top = 0;
00115 rect.right = dlgInfo.cx * xUnit / 4;
00116 rect.bottom = dlgInfo.cy * yUnit / 8;
00117 if (dlgInfo.style & DS_MODALFRAME)
00118 dlgInfo.exStyle |= WS_EX_DLGMODALFRAME;
00119
00120 AdjustWindowRectEx( &rect, dlgInfo.style, hMenu ? TRUE : FALSE , dlgInfo.exStyle );
00121 rect.right -= rect.left;
00122 rect.bottom -= rect.top;
00123
00124 if ((INT16)dlgInfo.x == CW_USEDEFAULT16)
00125 {
00126 rect.left = rect.top = CW_USEDEFAULT;
00127 }
00128 else
00129 {
00130 if (dlgInfo.style & DS_CENTER)
00131 {
00132 rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2;
00133 rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2;
00134 }
00135 else
00136 {
00137 rect.left += dlgInfo.x * xUnit / 4;
00138 rect.top += dlgInfo.y * yUnit / 8;
00139 }
00140 if ( !(dlgInfo.style & WS_CHILD) )
00141 {
00142 INT dX, dY;
00143
00144 if( !(dlgInfo.style & DS_ABSALIGN) && owner)
00145 ClientToScreen(owner, (POINT *)&rect );
00146
00147
00148
00149 if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME)
00150 - GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX;
00151 if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME)
00152 - GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY;
00153 if( rect.left < 0 ) rect.left = 0;
00154 if( rect.top < 0 ) rect.top = 0;
00155 }
00156 }
00157
00158
00159
00160
00161 if (!HIWORD(dlgInfo.className))
00162 {
00163 classAtom = (ATOM)LOWORD(dlgInfo.className);
00164 }
00165 else
00166 if (!(classAtom = GlobalFindAtomW((LPWSTR)dlgInfo.className)))
00167 {
00168 SetLastError(ERROR_INVALID_PARAMETER);
00169 return;
00170 }
00171 CREATESTRUCTA cs;
00172 cs.lpCreateParams = NULL;
00173 cs.hInstance = hInst;
00174 cs.hMenu = hMenu;
00175 cs.hwndParent = owner;
00176 cs.x = rect.left;
00177 cs.y = rect.top;
00178 cs.cx = rect.right;
00179 cs.cy = rect.bottom;
00180 cs.style = dlgInfo.style & ~WS_VISIBLE;
00181
00182 if(!isUnicode) {
00183 if(dlgInfo.caption) {
00184 cs.lpszName = UnicodeToAsciiString((LPWSTR)dlgInfo.caption);
00185 }
00186 else cs.lpszName = 0;
00187 if(dlgInfo.className) {
00188 cs.lpszClass = UnicodeToAsciiString((LPWSTR)dlgInfo.className);
00189 }
00190 else cs.lpszClass = 0;
00191 }
00192 else {
00193 cs.lpszName = dlgInfo.caption;
00194 cs.lpszClass = dlgInfo.className;
00195 }
00196 cs.dwExStyle = dlgInfo.exStyle;
00197 if (dlgInfo.style & DS_CONTEXTHELP) cs.dwExStyle |= WS_EX_CONTEXTHELP;
00198
00199
00200
00201
00202 if (dlgInfo.style & DS_CONTROL) cs.style &= ~(WS_CAPTION);
00203
00204 fIsDialog = TRUE;
00205 WINPROC_SetProc((HWINDOWPROC *)&Win32DlgProc, (WNDPROC)dlgProc, (isUnicode) ? WIN_PROC_32W : WIN_PROC_32A, WIN_PROC_WINDOW);
00206
00207 this->tmpParam = param;
00208 this->tmpDlgTemplate = (LPSTR)dlgTemplate;
00209
00210 if (CreateWindowExA(&cs, classAtom) == FALSE)
00211 {
00212 if (hUserFont) DeleteObject( hUserFont );
00213 if (hMenu) DestroyMenu( hMenu );
00214 SetLastError(ERROR_OUTOFMEMORY);
00215 return;
00216 }
00217 SetLastError(0);
00218 return;
00219 }
00220
00221
00222 Win32Dialog::~Win32Dialog()
00223 {
00224 if (hUserFont) DeleteObject( hUserFont );
00225 if (hMenu) DestroyMenu( hMenu );
00226
00227 WINPROC_FreeProc(Win32DlgProc, WIN_PROC_WINDOW);
00228 }
00229
00230
00231 ULONG Win32Dialog::MsgCreate(HWND hwndOS2)
00232 {
00233 CREATESTRUCTA *cs = tmpcs;
00234 LPARAM param = tmpParam;
00235 LPSTR dlgTemplate = tmpDlgTemplate;
00236
00237 if(Win32BaseWindow::MsgCreate(hwndOS2) == FALSE) {
00238 dprintf(("********* DIALOG CREATION FAILED! (main dialog window) ************"));
00239 return FALSE;
00240 }
00241
00242 if(!isUnicode) {
00243 if(cs->lpszName) FreeAsciiString((LPSTR)cs->lpszName);
00244 if(HIWORD(cs->lpszClass)) {
00245 FreeAsciiString((LPSTR)cs->lpszClass);
00246 }
00247 }
00248
00249 if (hUserFont)
00250 SendInternalMessageA(WM_SETFONT, (WPARAM)hUserFont, 0 );
00251
00252
00253 if (createControls(dlgTemplate, hInstance))
00254 {
00255 dprintf(("********* DIALOG CONTROLS CREATED ************"));
00256
00257 hwndFocus = GetNextDlgTabItem( getWindowHandle(), 0, FALSE );
00258 dprintf(("dlg ctor: GetNextDlgTabItem returned %x, capture hwnd = %x", hwndFocus, GetCapture()));
00259
00260 fDialogInit = TRUE;
00261
00262 HWND hwndPreInitFocus = GetFocus();
00263 if(SendInternalMessageA(WM_INITDIALOG, (WPARAM)hwndFocus, param))
00264 {
00265
00266
00267
00268 if(!(getStyle() & WS_CHILD))
00269 {
00270
00271
00272 hwndFocus = GetNextDlgTabItem( getWindowHandle(), 0, FALSE );
00273 if(GetFocus() != hwndFocus) {
00274 SetFocus(hwndFocus);
00275 }
00276 }
00277 }
00278 else
00279 {
00280
00281
00282
00283 if(!(getStyle() & WS_CHILD))
00284 {
00285
00286
00287 if ( (getStyle() & WS_VISIBLE) && ( GetFocus() == hwndPreInitFocus ) )
00288 SetFocus( hwndFocus );
00289 }
00290 }
00291
00292 if (dlgInfo.style & WS_VISIBLE && !(getStyle() & WS_VISIBLE))
00293 {
00294 ShowWindow( SW_SHOWNORMAL );
00295 UpdateWindow( getWindowHandle() );
00296 }
00297 SetLastError(ERROR_SUCCESS);
00298 dprintf(("********* DIALOG CREATED ************"));
00299 return TRUE;
00300 }
00301 dprintf(("********* DIALOG CREATION FAILED! ************"));
00302 return FALSE;
00303 }
00304
00305
00306 BOOL Win32Dialog::MapDialogRect(LPRECT rect)
00307 {
00308 rect->left = (rect->left * xUnit) / 4;
00309 rect->right = (rect->right * xUnit) / 4;
00310 rect->top = (rect->top * yUnit) / 8;
00311 rect->bottom = (rect->bottom * yUnit) / 8;
00312 return TRUE;
00313 }
00314
00315
00316
00317 INT Win32Dialog::doDialogBox()
00318 {
00319 Win32BaseWindow *topOwner;
00320 MSG msg;
00321 INT retval;
00322
00323 dprintf(("doDialogBox %x", getWindowHandle()));
00324
00325 if(getOwner() == NULL) {
00326 windowDesktop->addRef();
00327 topOwner = windowDesktop;
00328 }
00329 else topOwner = GetWindowFromHandle(getOwner()->GetTopParent());
00330
00331 if(topOwner == NULL) {
00332 dprintf(("Dialog box has no top owner!!!"));
00333 return -1;
00334 }
00335
00336 if (!dialogFlags & DF_END)
00337 {
00338 HWND hwndOldDialog;
00339 BOOL bOldOwner;
00340
00341 fIsModalDialog = TRUE;
00342 topOwner->EnableWindow(FALSE);
00343
00344 bOldOwner = topOwner->IsModalDialogOwner();
00345 topOwner->setModalDialogOwner(TRUE);
00346 hwndOldDialog = topOwner->getOS2HwndModalDialog();
00347 topOwner->setOS2HwndModalDialog(OS2HwndFrame);
00348 ShowWindow(SW_SHOW);
00349
00350
00351
00352
00353
00354 while (TRUE)
00355 {
00356 if (!PeekMessageA(&msg,0,0,0,PM_NOREMOVE))
00357 {
00358 if(!(getStyle() & DS_NOIDLEMSG))
00359 topOwner->SendMessageA(WM_ENTERIDLE,MSGF_DIALOGBOX,getWindowHandle());
00360 GetMessageA(&msg,0,0,0);
00361 }
00362 else PeekMessageA(&msg,0,0,0,PM_REMOVE);
00363
00364
00365 if (HOOK_IsHooked( WH_SYSMSGFILTER ) || HOOK_IsHooked( WH_MSGFILTER ))
00366 {
00367 LPMSG pmsg = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
00368 if (pmsg)
00369 {
00370 BOOL ret;
00371 *pmsg = msg;
00372 ret = (HOOK_CallHooksA( WH_SYSMSGFILTER, MSGF_DIALOGBOX, 0,
00373 (LPARAM) pmsg ) ||
00374 HOOK_CallHooksA( WH_MSGFILTER, MSGF_DIALOGBOX, 0,
00375 (LPARAM) pmsg ));
00376
00377 HeapFree( GetProcessHeap(), 0, pmsg );
00378 if (ret)
00379 {
00380
00381
00382 continue;
00383 }
00384 }
00385 }
00386
00387 if(msg.message == WM_QUIT)
00388 {
00389 dprintf(("Win32Dialog::doDialogBox: received WM_QUIT"));
00390 break;
00391 }
00392 if (!IsDialogMessageA( getWindowHandle(), &msg))
00393 {
00394 TranslateMessage( &msg );
00395 DispatchMessageA( &msg );
00396 }
00397 if (dialogFlags & DF_END)
00398 break;
00399 }
00400 topOwner->setModalDialogOwner(bOldOwner);
00401 topOwner->setOS2HwndModalDialog(hwndOldDialog);
00402 if (!bOldOwner) topOwner->EnableWindow(TRUE);
00403 }
00404 RELEASE_WNDOBJ(topOwner);
00405 retval = idResult;
00406 DestroyWindow();
00407 return retval;
00408 }
00409
00410
00411
00412
00413
00414 BOOL Win32Dialog::DIALOG_Init(void)
00415 {
00416 HDC hdc;
00417 SIZE size;
00418
00419
00420 if (!(hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
00421 if (!getCharSizeFromDC( hdc, 0, &size )) return FALSE;
00422 DeleteDC( hdc );
00423 xBaseUnit = size.cx;
00424 yBaseUnit = size.cy;
00425
00426 return TRUE;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435 BOOL Win32Dialog::getCharSizeFromDC( HDC hDC, HFONT hUserFont, SIZE * pSize )
00436 {
00437 BOOL Success = FALSE;
00438 HFONT hFontPrev = 0;
00439 pSize->cx = xBaseUnit;
00440 pSize->cy = yBaseUnit;
00441
00442 if ( hDC )
00443 {
00444
00445 TEXTMETRICA tm;
00446 memset(&tm,0,sizeof(tm));
00447 if (hUserFont) hFontPrev = SelectFont(hDC,hUserFont);
00448 if (GetTextMetricsA(hDC,&tm))
00449 {
00450 pSize->cx = tm.tmAveCharWidth;
00451 pSize->cy = tm.tmHeight;
00452
00453
00454 if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
00455 {
00456 SIZE total;
00457 static const char szAvgChars[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
00458
00459
00460
00461
00462
00463
00464
00465 #ifdef __WIN32OS2__
00466 if (GetTextExtentPointA(hDC,szAvgChars,sizeof(szAvgChars)-1,&total))
00467 {
00468
00469 pSize->cx = ((2*total.cx/(sizeof(szAvgChars)-1)) + 1)/2;
00470 Success = TRUE;
00471 }
00472 #else
00473 if (GetTextExtentPointA(hDC,szAvgChars,sizeof(szAvgChars),&total))
00474 {
00475
00476 pSize->cx = ((2*total.cx/sizeof(szAvgChars)) + 1)/2;
00477 Success = TRUE;
00478 }
00479 #endif
00480 }
00481 else
00482 {
00483 Success = TRUE;
00484 }
00485 }
00486
00487
00488 if (hFontPrev) SelectFont(hDC,hFontPrev);
00489 }
00490 return (Success);
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500 BOOL Win32Dialog::getCharSize( HFONT hUserFont, SIZE * pSize )
00501 {
00502 HDC hDC = CreateCompatibleDC(0);
00503 BOOL Success = getCharSizeFromDC( hDC, hUserFont, pSize );
00504 DeleteDC(hDC);
00505 return Success;
00506 }
00507
00508
00509
00510
00511
00512
00513 LPCSTR Win32Dialog::parseTemplate( LPCSTR dlgtemplate, DLG_TEMPLATE * result )
00514 {
00515 const WORD *p = (const WORD *)dlgtemplate;
00516
00517 result->style = GET_DWORD(p); p += 2;
00518 if (result->style == 0xffff0001)
00519 {
00520 result->dialogEx = TRUE;
00521 result->helpId = GET_DWORD(p); p += 2;
00522 result->exStyle = GET_DWORD(p); p += 2;
00523 result->style = GET_DWORD(p); p += 2;
00524 }
00525 else
00526 {
00527 result->dialogEx = FALSE;
00528 result->helpId = 0;
00529 result->exStyle = GET_DWORD(p); p += 2;
00530 }
00531 result->nbItems = GET_WORD(p); p++;
00532
00533 result->x = GET_SHORT(p); p++;
00534 result->y = GET_SHORT(p); p++;
00535 result->cx = GET_WORD(p); p++;
00536 result->cy = GET_WORD(p); p++;
00537
00538
00539
00540 switch(GET_WORD(p))
00541 {
00542 case 0x0000:
00543 result->menuName = NULL;
00544 p++;
00545 break;
00546 case 0xffff:
00547 result->menuName = (LPCSTR)(UINT)GET_WORD( p + 1 );
00548 p += 2;
00549 break;
00550 default:
00551 result->menuName = (LPCSTR)p;
00552 p += lstrlenW( (LPCWSTR)p ) + 1;
00553 break;
00554 }
00555
00556
00557 switch(GET_WORD(p))
00558 {
00559 case 0x0000:
00560 result->className = (LPCSTR)DIALOG_CLASS_NAMEW;
00561 p++;
00562 break;
00563 case 0xffff:
00564 result->className = (LPCSTR)(UINT)GET_WORD( p + 1 );
00565 p += 2;
00566 break;
00567 default:
00568 result->className = (LPCSTR)p;
00569 p += lstrlenW( (LPCWSTR)p ) + 1;
00570 break;
00571 }
00572
00573
00574
00575 result->caption = (LPCSTR)p;
00576 p += lstrlenW( (LPCWSTR)p ) + 1;
00577
00578
00579
00580 if (result->style & DS_SETFONT)
00581 {
00582 result->pointSize = GET_WORD(p);
00583 p++;
00584 if (result->dialogEx)
00585 {
00586 result->weight = GET_WORD(p); p++;
00587 result->italic = LOBYTE(GET_WORD(p)); p++;
00588 }
00589 else
00590 {
00591 result->weight = FW_DONTCARE;
00592 result->italic = FALSE;
00593 }
00594 result->faceName = (LPCSTR)p;
00595 p += lstrlenW( (LPCWSTR)p ) + 1;
00596 }
00597
00598
00599 return (LPCSTR)((((int)p) + 3) & ~3);
00600 }
00601
00602
00603
00604
00605
00606
00607 WORD *Win32Dialog::getControl(const WORD *p, DLG_CONTROL_INFO *info, BOOL dialogEx)
00608 {
00609 if (dialogEx)
00610 {
00611 info->helpId = GET_DWORD(p); p += 2;
00612 info->exStyle = GET_DWORD(p); p += 2;
00613 info->style = GET_DWORD(p); p += 2;
00614 }
00615 else
00616 {
00617 info->helpId = 0;
00618 info->style = GET_DWORD(p); p += 2;
00619 info->exStyle = GET_DWORD(p); p += 2;
00620 }
00621
00622 info->x = GET_SHORT(p); p++;
00623 info->y = GET_SHORT(p); p++;
00624 info->cx = GET_WORD(p); p++;
00625 info->cy = GET_WORD(p); p++;
00626
00627 if (dialogEx)
00628 {
00629
00630 info->id = GET_DWORD(p);
00631 p += 2;
00632 }
00633 else
00634 {
00635 info->id = GET_WORD(p);
00636 p++;
00637 }
00638
00639 if (GET_WORD(p) == 0xffff)
00640 {
00641 static const WCHAR class_names[6][10] =
00642 {
00643 { 'B','u','t','t','o','n', },
00644 { 'E','d','i','t', },
00645 { 'S','t','a','t','i','c', },
00646 { 'L','i','s','t','B','o','x', },
00647 { 'S','c','r','o','l','l','B','a','r', },
00648 { 'C','o','m','b','o','B','o','x', }
00649 };
00650 WORD id = GET_WORD(p+1);
00651 if ((id >= 0x80) && (id <= 0x85))
00652 info->className = (LPCSTR)class_names[id - 0x80];
00653 else
00654 {
00655 info->className = NULL;
00656 dprintf(("Unknown built-in class id %04x\n", id ));
00657 }
00658 p += 2;
00659 }
00660 else
00661 {
00662 info->className = (LPCSTR)p;
00663 p += lstrlenW( (LPCWSTR)p ) + 1;
00664 }
00665
00666 if (GET_WORD(p) == 0xffff)
00667 {
00668 info->windowName = (LPCSTR)(UINT)GET_WORD(p + 1);
00669
00670
00671 p += 2;
00672 }
00673 else
00674 {
00675 info->windowName = (LPCSTR)p;
00676 p += lstrlenW( (LPCWSTR)p ) + 1;
00677 }
00678
00679 if (GET_WORD(p))
00680 {
00681 info->data = (LPVOID)(p + 1);
00682 p += GET_WORD(p) / sizeof(WORD);
00683 }
00684 else info->data = NULL;
00685 p++;
00686
00687
00688 return (WORD *)((((int)p) + 3) & ~3);
00689 }
00690
00691
00692
00693
00694
00695
00696
00697 BOOL Win32Dialog::createControls(LPCSTR dlgtemplate, HINSTANCE hInst)
00698 {
00699 DLG_CONTROL_INFO info;
00700 HWND hwndCtrl, hwndDefButton = 0;
00701 INT items = dlgInfo.nbItems;
00702
00703 while (items--)
00704 {
00705 dlgtemplate = (LPCSTR)getControl( (WORD *)dlgtemplate, &info, dlgInfo.dialogEx );
00706
00707 dprintf(("Create CONTROL %d", info.id));
00708
00709 hwndCtrl = ::CreateWindowExW( info.exStyle | WS_EX_NOPARENTNOTIFY,
00710 (LPWSTR)info.className,
00711 (LPWSTR)info.windowName,
00712 info.style | WS_CHILD,
00713 MulDiv(info.x, xUnit, 4),
00714 MulDiv(info.y, yUnit, 8),
00715 MulDiv(info.cx, xUnit, 4),
00716 MulDiv(info.cy, yUnit, 8),
00717 getWindowHandle(), (HMENU)info.id,
00718 hInst, info.data );
00719
00720 if (!hwndCtrl) return FALSE;
00721
00722
00723 if (hUserFont) ::SendMessageA( hwndCtrl, WM_SETFONT, (WPARAM)hUserFont, 0 );
00724
00725 if (::SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
00726 {
00727
00728
00729 if (hwndDefButton)
00730 ::SendMessageA( hwndDefButton, BM_SETSTYLE,
00731 BS_PUSHBUTTON,FALSE );
00732 hwndDefButton = hwndCtrl;
00733 idResult = ::GetWindowWord( hwndCtrl, GWW_ID );
00734 }
00735 dprintf(("Create CONTROL %d DONE", info.id));
00736 }
00737 return TRUE;
00738 }
00739
00740
00741
00742
00743
00744
00745 LRESULT Win32Dialog::DefDlg_Proc(UINT msg, WPARAM wParam, LPARAM lParam)
00746 {
00747 switch(msg)
00748 {
00749 case WM_ERASEBKGND:
00750 {
00751 RECT rect;
00752 int rc;
00753
00754 if (!windowClass) return 0;
00755
00756 rc = GetClipBox( (HDC)wParam, &rect );
00757 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
00758 {
00759 HBRUSH hBrush = SendInternalMessageA(WM_CTLCOLORDLG, wParam, getWindowHandle());
00760 if(GetObjectType(hBrush) != OBJ_BRUSH) {
00761 DefWndControlColor(CTLCOLOR_DLG, (HDC)wParam);
00762 }
00763 FillRect( (HDC)wParam, &rect, hBrush);
00764 }
00765
00766 return 1;
00767 }
00768
00769 case WM_NCDESTROY:
00770
00771 #if 0
00772 if (dlgInfo->hDialogHeap)
00773 {
00774 GlobalUnlock16(dlgInfo->hDialogHeap);
00775 GlobalFree16(dlgInfo->hDialogHeap);
00776 dlgInfo->hDialogHeap = 0;
00777 }
00778 #endif
00779
00780 if (hUserFont)
00781 {
00782 DeleteObject( hUserFont );
00783 hUserFont = 0;
00784 }
00785
00786
00787 if (hMenu)
00788 {
00789 DestroyMenu( hMenu );
00790 hMenu = 0;
00791 }
00792
00793
00794 Win32DlgProc = 0;
00795 dialogFlags |= DF_END;
00796
00797
00798 return DefWindowProcA(msg, wParam, lParam );
00799
00800 case WM_SHOWWINDOW:
00801 if (!wParam) saveFocus();
00802 return DefWindowProcA(msg, wParam, lParam );
00803
00804 case WM_ACTIVATE:
00805 if (wParam) {
00806 restoreFocus();
00807 }
00808 else saveFocus();
00809 return 0;
00810
00811 case WM_SETFOCUS:
00812 restoreFocus();
00813 return 0;
00814
00815 case DM_SETDEFID:
00816 if (dialogFlags & DF_END)
00817 return 1;
00818
00819 setDefButton(wParam ? GetDlgItem( getWindowHandle(), wParam ) : 0 );
00820 return 1;
00821
00822 case DM_GETDEFID:
00823 {
00824 HWND hwndDefId;
00825 if (dialogFlags & DF_END) return 0;
00826 if (idResult)
00827 return MAKELONG( idResult, DC_HASDEFID );
00828 if ((hwndDefId = findDefButton()) != 0)
00829 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
00830
00831 return 0;
00832 }
00833
00834 case WM_NEXTDLGCTL:
00835 {
00836 HWND hwndDest = (HWND)wParam;
00837 if (!lParam)
00838 hwndDest = GetNextDlgTabItem(getWindowHandle(), GetFocus(), wParam);
00839 if (hwndDest) setFocus( hwndDest );
00840 setDefButton( hwndDest );
00841 return 0;
00842 }
00843
00844 case WM_ENTERMENULOOP:
00845 case WM_LBUTTONDOWN:
00846 case WM_NCLBUTTONDOWN:
00847 {
00848 HWND hwndCurFocus = GetFocus();
00849 if (hwndCurFocus)
00850 {
00851 Win32BaseWindow *wndFocus = Win32BaseWindow::GetWindowFromHandle(hwndFocus);
00852
00853 if(wndFocus)
00854 {
00855
00856 if( CONTROLS_IsControl( wndFocus, COMBOBOX_CONTROL ) )
00857 wndFocus->SendMessageA(CB_SHOWDROPDOWN, FALSE, 0 );
00858 else
00859 if( CONTROLS_IsControl( wndFocus, EDIT_CONTROL ) &&
00860 CONTROLS_IsControl( wndFocus->getParent(), COMBOBOX_CONTROL ))
00861 wndFocus->SendMessageA(CB_SHOWDROPDOWN, FALSE, 0 );
00862 RELEASE_WNDOBJ(wndFocus);
00863 }
00864 }
00865 return DefWindowProcA( msg, wParam, lParam );
00866 }
00867
00868 case WM_GETFONT:
00869 return hUserFont;
00870
00871 case WM_CLOSE:
00872 PostMessageA(getWindowHandle(), WM_COMMAND, IDCANCEL, (LPARAM)GetDlgItem( getWindowHandle(), IDCANCEL ) );
00873 return 0;
00874
00875 case WM_NOTIFYFORMAT:
00876 return DefWindowProcA(msg, wParam, lParam );
00877 }
00878 return 0;
00879 }
00880
00881
00882 LRESULT Win32Dialog::DefDlgProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
00883 {
00884 BOOL result = FALSE;
00885
00886 msgResult = 0;
00887
00888
00889 if (Msg == WM_CREATE || Msg == WM_NCCREATE) {
00890 return (LRESULT)1;
00891 }
00892
00893
00894 if(!fDialogInit && Msg == WM_NCCALCSIZE) {
00895 return DefWindowProcA(Msg, wParam, lParam );
00896 }
00897
00898 if (Win32DlgProc) {
00899 result = Win32DlgProc(getWindowHandle(), Msg, wParam, lParam);
00900 }
00901
00902 if (!result && IsWindow())
00903 {
00904
00905 switch(Msg)
00906 {
00907 case WM_ERASEBKGND:
00908 case WM_SHOWWINDOW:
00909 case WM_ACTIVATE:
00910 case WM_SETFOCUS:
00911 case DM_SETDEFID:
00912 case DM_GETDEFID:
00913 case WM_NEXTDLGCTL:
00914 case WM_GETFONT:
00915 case WM_CLOSE:
00916 case WM_NCDESTROY:
00917 case WM_ENTERMENULOOP:
00918 case WM_LBUTTONDOWN:
00919 case WM_NCLBUTTONDOWN:
00920 return DefDlg_Proc(Msg, (WPARAM)wParam, lParam);
00921
00922 case WM_INITDIALOG:
00923 case WM_VKEYTOITEM:
00924 case WM_COMPAREITEM:
00925 case WM_CHARTOITEM:
00926 break;
00927
00928 default:
00929 return DefWindowProcA(Msg, wParam, lParam );
00930 }
00931 }
00932 return DefDlg_Epilog(Msg, result);
00933 }
00934
00935
00936 LRESULT Win32Dialog::DefDlgProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
00937 {
00938 BOOL result = FALSE;
00939
00940 msgResult = 0;
00941
00942
00943 if (Msg == WM_CREATE || Msg == WM_NCCREATE) {
00944 return (LRESULT)1;
00945 }
00946
00947
00948 if(!fDialogInit && Msg == WM_NCCALCSIZE) {
00949 return DefWindowProcW(Msg, wParam, lParam );
00950 }
00951
00952 if (Win32DlgProc) {
00953 result = Win32DlgProc(getWindowHandle(), Msg, wParam, lParam);
00954 }
00955
00956 if (!result && IsWindow())
00957 {
00958
00959 switch(Msg)
00960 {
00961 case WM_ERASEBKGND:
00962 case WM_SHOWWINDOW:
00963 case WM_ACTIVATE:
00964 case WM_SETFOCUS:
00965 case DM_SETDEFID:
00966 case DM_GETDEFID:
00967 case WM_NEXTDLGCTL:
00968 case WM_GETFONT:
00969 case WM_CLOSE:
00970 case WM_NCDESTROY:
00971 case WM_ENTERMENULOOP:
00972 case WM_LBUTTONDOWN:
00973 case WM_NCLBUTTONDOWN:
00974 return DefDlg_Proc(Msg, (WPARAM)wParam, lParam);
00975
00976 case WM_INITDIALOG:
00977 case WM_VKEYTOITEM:
00978 case WM_COMPAREITEM:
00979 case WM_CHARTOITEM:
00980 break;
00981
00982 default:
00983 return DefWindowProcW(Msg, wParam, lParam );
00984 }
00985 }
00986 return DefDlg_Epilog(Msg, result);
00987 }
00988
00989
00990
00991 LRESULT Win32Dialog::DefDlg_Epilog(UINT msg, BOOL fResult)
00992 {
00993
00994 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
00995 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
00996 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
00997 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
00998 return fResult;
00999
01000 return msgResult;
01001 }
01002
01003
01004
01005
01006
01007
01008 void Win32Dialog::setFocus(HWND hwndCtrl )
01009 {
01010 HWND hwndPrev = GetFocus();
01011
01012 if (IsChild( hwndPrev ))
01013 {
01014 if (::SendMessageA( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
01015 ::SendMessageA( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
01016 }
01017 if (::SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
01018 ::SendMessageA(hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
01019 SetFocus( hwndCtrl );
01020 }
01021
01022
01023
01024
01025
01026 BOOL Win32Dialog::saveFocus()
01027 {
01028 HWND hwndCurrentFocus = GetFocus();
01029
01030 if (!hwndCurrentFocus || !IsChild( hwndCurrentFocus )) return FALSE;
01031
01032 hwndFocus = hwndCurrentFocus;
01033
01034 return TRUE;
01035 }
01036
01037
01038
01039
01040
01041 BOOL Win32Dialog::restoreFocus()
01042 {
01043 if (!hwndFocus || IsWindowIconic()) return FALSE;
01044
01045 if (!::IsWindow( hwndFocus )) return FALSE;
01046
01047
01048 if (!(dialogFlags & DF_END))
01049 setFocus(hwndFocus);
01050
01051
01052
01053 return TRUE;
01054 }
01055
01056
01057
01058
01059
01060
01061
01062 HWND Win32Dialog::findDefButton()
01063 {
01064 HWND hwndChild = GetWindow( GW_CHILD );
01065 while (hwndChild)
01066 {
01067 if (::SendMessageA( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
01068 break;
01069 hwndChild = ::GetWindow( hwndChild, GW_HWNDNEXT );
01070 }
01071 return hwndChild;
01072 }
01073
01074
01075
01076
01077
01078
01079
01080 BOOL Win32Dialog::setDefButton(HWND hwndNew )
01081 {
01082 if (hwndNew &&
01083 !(::SendMessageA(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
01084 return FALSE;
01085
01086 if (idResult)
01087 {
01088 HWND hwndOld = GetDlgItem( getWindowHandle(), idResult );
01089 if (::SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
01090 ::SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
01091 }
01092 if (hwndNew)
01093 {
01094 ::SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
01095 idResult = GetDlgCtrlID( hwndNew );
01096 }
01097 else idResult = 0;
01098 return TRUE;
01099 }
01100
01101
01102 BOOL Win32Dialog::endDialog(int retval)
01103 {
01104 HWND hwnd = getWindowHandle();
01105
01106 dialogFlags |= DF_END;
01107 idResult = retval;
01108
01109
01110
01111
01112
01113
01114
01115
01116 if (::IsChild(hwnd, GetFocus()))
01117 ::SetFocus( hwnd );
01118
01119
01120
01121
01122 ::SetWindowPos(hwnd, (HWND)0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
01123 | SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW);
01124
01125
01126 PostMessageA(hwnd, WM_NULL, 0, 0);
01127 return TRUE;
01128 }
01129
01130
01131 LONG Win32Dialog::SetWindowLong(int index, ULONG value, BOOL fUnicode)
01132 {
01133 LONG oldval;
01134
01135 dprintf2(("Win32Dialog::SetWindowLongA %x %d %x", getWindowHandle(), index, value));
01136 switch(index)
01137 {
01138 case DWL_DLGPROC:
01139 {
01140
01141
01142
01143
01144 WINDOWPROCTYPE type = WINPROC_GetProcType((HWINDOWPROC)value);
01145 if(type == WIN_PROC_INVALID) {
01146 type = (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A;
01147 }
01148 oldval = (LONG)WINPROC_GetProc(Win32DlgProc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
01149 WINPROC_SetProc((HWINDOWPROC *)&Win32DlgProc, (WNDPROC)value, type, WIN_PROC_WINDOW);
01150 return oldval;
01151 }
01152 case DWL_MSGRESULT:
01153 oldval = msgResult;
01154 msgResult = value;
01155 return oldval;
01156 case DWL_USER:
01157 oldval = userDlgData;
01158 userDlgData = value;
01159 return oldval;
01160 default:
01161 return Win32BaseWindow::SetWindowLong(index, value, fUnicode);
01162 }
01163 }
01164
01165
01166 ULONG Win32Dialog::GetWindowLong(int index, BOOL fUnicode)
01167 {
01168 dprintf2(("Win32Dialog::GetWindowLongA %x %d", getWindowHandle(), index));
01169 switch(index)
01170 {
01171 case DWL_DLGPROC:
01172 return (ULONG)WINPROC_GetProc(Win32DlgProc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
01173 case DWL_MSGRESULT:
01174 return msgResult;
01175 case DWL_USER:
01176 return userDlgData;
01177 default:
01178 return Win32BaseWindow::GetWindowLong(index, fUnicode);
01179 }
01180 }
01181
01182
01183 BOOL DIALOG_Register()
01184 {
01185 WNDCLASSA wndClass;
01186
01187 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
01188 wndClass.style = CS_GLOBALCLASS | CS_SAVEBITS;
01189 wndClass.lpfnWndProc = (WNDPROC)DefDlgProcA;
01190 wndClass.cbClsExtra = 0;
01191 wndClass.cbWndExtra = 0;
01192 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);
01193 wndClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
01194 wndClass.lpszClassName = DIALOG_CLASS_NAMEA;
01195
01196 return RegisterClassA(&wndClass);
01197 }
01198
01199
01200 BOOL DIALOG_Unregister()
01201 {
01202 if (GlobalFindAtomA(DIALOG_CLASS_NAMEA))
01203 return UnregisterClassA(DIALOG_CLASS_NAMEA,(HINSTANCE)NULL);
01204 else return FALSE;
01205 }
01206
01207
01208 BOOL Win32Dialog::fInitialized = FALSE;
01209 int Win32Dialog::xBaseUnit = 10;
01210 int Win32Dialog::yBaseUnit = 20;