Ignore:
Timestamp:
Sep 4, 1999, 9:42:30 PM (26 years ago)
Author:
sandervl
Message:

Dialog changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/new/win32dlg.cpp

    r741 r821  
    1 /* $Id: win32dlg.cpp,v 1.2 1999-08-30 11:59:53 sandervl Exp $ */
     1/* $Id: win32dlg.cpp,v 1.3 1999-09-04 19:42:28 sandervl Exp $ */
    22/*
    33 * Win32 Dialog Code for OS/2
    44 *
    5  *
    6  * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
    7  *
     5 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl) (Wine port & OS/2 adaption)
     6 *
     7 * Based on Wine code (990815; windows\dialog.c)
     8 *
     9 * Copyright 1993, 1994, 1996 Alexandre Julliard
    810 *
    911 * Project Odin Software License can be found in LICENSE.TXT
     
    1113 */
    1214#include <os2win.h>
     15#include <windowsx.h>
    1316#include <stdlib.h>
    1417#include <string.h>
     
    1821//******************************************************************************
    1922//******************************************************************************
    20 Win32Dialog::Win32Dialog() : Win32BaseWindow(OBJTYPE_DIALOG)
    21 {
     23Win32Dialog::Win32Dialog(HINSTANCE hInst, LPCSTR dlgTemplate, HWND owner,
     24                         DLGPROC dlgProc, LPARAM param, BOOL isUnicode)
     25                    : Win32BaseWindow(OBJTYPE_DIALOG)
     26{
     27  RECT rect;
     28  WORD style;
     29  ATOM classAtom;
     30
     31    this->isUnicode = isUnicode;
     32    hUserFont        = 0;
     33    hMenu        = 0;
     34        hwndFocus    = 0;
     35    Win32DlgProc = 0;
     36    msgResult    = 0;
     37    userDlgData  = 0;
     38    idResult     = 0;
     39    dialogFlags  = 0;
     40    memset(&dlgInfo, 0, sizeof(dlgInfo));
     41
     42    if(fInitialized == FALSE) {
     43        if(DIALOG_Init() == FALSE) {
     44            dprintf(("DIALOG_Init FAILED!"));
     45            DebugInt3();
     46            SetLastError(ERROR_GEN_FAILURE);
     47            return;
     48        }
     49        fInitialized = TRUE;
     50    }
     51    xUnit = xBaseUnit;
     52    yUnit = yBaseUnit;
     53
     54    /* Parse dialog template */
     55    dlgTemplate = parseTemplate(dlgTemplate, &dlgInfo);
     56
     57    /* Load menu */
     58    if (dlgInfo.menuName)
     59    {
     60        hMenu = LoadMenuW( hInst, (LPCWSTR)dlgInfo.menuName );
     61    }
     62
     63    /* Create custom font if needed */
     64    if (dlgInfo.style & DS_SETFONT)
     65    {
     66        /* The font height must be negative as it is a point size */
     67        /* (see CreateFont() documentation in the Windows SDK).   */
     68        hUserFont = CreateFontW(dlgInfo.pointSize, 0, 0, 0,
     69                            dlgInfo.weight, dlgInfo.italic, FALSE,
     70                            FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY,
     71                            FF_DONTCARE, (LPCWSTR)dlgInfo.faceName );
     72        if (hUserFont)
     73        {
     74            SIZE charSize;
     75            getCharSize(hUserFont,&charSize);
     76            xBaseUnit = charSize.cx;
     77            yBaseUnit = charSize.cy;
     78        }
     79    }
     80
     81    /* Create dialog main window */
     82    rect.left = rect.top = 0;
     83    rect.right = dlgInfo.cx * xUnit / 4;
     84    rect.bottom = dlgInfo.cy * yUnit / 8;
     85    if (dlgInfo.style & DS_MODALFRAME)
     86        dlgInfo.exStyle |= WS_EX_DLGMODALFRAME;
     87
     88    AdjustWindowRectEx( &rect, dlgInfo.style, hMenu ? TRUE : FALSE , dlgInfo.exStyle );
     89    rect.right -= rect.left;
     90    rect.bottom -= rect.top;
     91
     92    if ((INT16)dlgInfo.x == CW_USEDEFAULT16)
     93    {
     94        rect.left = rect.top = CW_USEDEFAULT;
     95    }
     96    else
     97    {
     98        if (dlgInfo.style & DS_CENTER)
     99        {
     100            rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2;
     101            rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2;
     102        }
     103        else
     104        {
     105            rect.left += dlgInfo.x * xUnit / 4;
     106            rect.top += dlgInfo.y * yUnit / 8;
     107        }
     108        if ( !(dlgInfo.style & WS_CHILD) )
     109        {
     110            INT dX, dY;
     111
     112            if( !(dlgInfo.style & DS_ABSALIGN) )
     113                ClientToScreen(owner, (POINT *)&rect );
     114
     115            /* try to fit it into the desktop */
     116
     117            if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME)
     118                 - GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX;
     119            if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME)
     120                 - GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY;
     121            if( rect.left < 0 ) rect.left = 0;
     122            if( rect.top < 0 ) rect.top = 0;
     123        }
     124    }
     125
     126    /* Create the dialog window */
     127
     128    /* Find the class atom */
     129    if (HIWORD(dlgInfo.className))
     130    {
     131        classAtom = (ATOM)LOWORD(dlgInfo.className);
     132    }
     133    else
     134    if(!(classAtom = GlobalFindAtomA(dlgInfo.className)))
     135    {
     136        SetLastError(ERROR_INVALID_PARAMETER);
     137        return;
     138    }
     139    CREATESTRUCTA cs;
     140    cs.lpCreateParams = NULL;
     141    cs.hInstance      = hInst;
     142    cs.hMenu          = hMenu;
     143    cs.hwndParent     = owner;
     144    cs.x              = rect.left;
     145    cs.y              = rect.top;
     146    cs.cx             = rect.right;
     147    cs.cy             = rect.bottom;
     148    cs.style          = dlgInfo.style & ~WS_VISIBLE;
     149    cs.lpszName       = dlgInfo.caption;
     150    cs.lpszClass      = dlgInfo.className;
     151    cs.dwExStyle      = dlgInfo.exStyle;
     152
     153    CreateWindowExA(&cs, classAtom);
     154
     155    if (!getWindowHandle())
     156    {
     157        if (hUserFont) DeleteObject( hUserFont );
     158        if (hMenu) DestroyMenu( hMenu );
     159        return;
     160    }
     161    fIsDialog = TRUE;
     162
     163//TODO:
     164//    wndPtr->helpContext = helpId;
     165    Win32DlgProc = dlgProc;
     166
     167    if (hUserFont)
     168        SendMessageA(WM_SETFONT, (WPARAM)hUserFont, 0 );
     169
     170    /* Create controls */
     171    if (createControls(dlgTemplate, hInst))
     172    {
     173        /* Send initialisation messages and set focus */
     174        hwndFocus = GetNextDlgTabItem( getWindowHandle(), 0, FALSE );
     175
     176        if (::SendMessageA(hwndFocus, WM_INITDIALOG, (WPARAM)hwndFocus, param ))
     177            SetFocus( hwndFocus );
     178
     179        if (dlgInfo.style & WS_VISIBLE && !(getStyle() & WS_VISIBLE))
     180        {
     181            ShowWindow( SW_SHOWNORMAL );    /* SW_SHOW doesn't always work */
     182            ::UpdateWindow( getWindowHandle() );
     183        }
     184        return;
     185    }
     186    DestroyWindow();
    22187}
    23188//******************************************************************************
     
    25190Win32Dialog::~Win32Dialog()
    26191{
    27 
     192    if (hUserFont) DeleteObject( hUserFont );
     193    if (hMenu) DestroyMenu( hMenu );
     194
     195}
     196/***********************************************************************
     197 *           DIALOG_Init
     198 *
     199 * Initialisation of the dialog manager.
     200 */
     201BOOL Win32Dialog::DIALOG_Init(void)
     202{
     203    HDC hdc;
     204    SIZE size;
     205
     206    /* Calculate the dialog base units */
     207    if (!(hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
     208    if (!getCharSizeFromDC( hdc, 0, &size )) return FALSE;
     209    DeleteDC( hdc );
     210    xBaseUnit = size.cx;
     211    yBaseUnit = size.cy;
     212
     213    return TRUE;
     214}
     215/***********************************************************************
     216 *           DIALOG_GetCharSizeFromDC
     217 *
     218 *
     219 *  Calculates the *true* average size of English characters in the
     220 *  specified font as oppposed to the one returned by GetTextMetrics.
     221 */
     222BOOL Win32Dialog::getCharSizeFromDC( HDC hDC, HFONT hUserFont, SIZE * pSize )
     223{
     224    BOOL Success = FALSE;
     225    HFONT hUserFontPrev = 0;
     226    pSize->cx = xBaseUnit;
     227    pSize->cy = yBaseUnit;
     228
     229    if ( hDC )
     230    {
     231        /* select the font */
     232        TEXTMETRICA tm;
     233        memset(&tm,0,sizeof(tm));
     234        if (hUserFont) hUserFontPrev = SelectFont(hDC,hUserFont);
     235        if (GetTextMetricsA(hDC,&tm))
     236        {
     237            pSize->cx = tm.tmAveCharWidth;
     238            pSize->cy = tm.tmHeight;
     239
     240            /* if variable width font */
     241            if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
     242            {
     243                SIZE total;
     244                static const char szAvgChars[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
     245
     246                /* Calculate a true average as opposed to the one returned
     247                 * by tmAveCharWidth. This works better when dealing with
     248                 * proportional spaced fonts and (more important) that's
     249                 * how Microsoft's dialog creation code calculates the size
     250                 * of the font
     251                 */
     252                if (GetTextExtentPointA(hDC,szAvgChars,sizeof(szAvgChars),&total))
     253                {
     254                   /* round up */
     255                    pSize->cx = ((2*total.cx/sizeof(szAvgChars)) + 1)/2;
     256                    Success = TRUE;
     257                }
     258            }
     259            else
     260            {
     261                Success = TRUE;
     262            }
     263        }
     264
     265        /* select the original font */
     266        if (hUserFontPrev) SelectFont(hDC,hUserFontPrev);
     267    }
     268    return (Success);
     269}
     270/***********************************************************************
     271 *           DIALOG_GetCharSize
     272 *
     273 *
     274 *  Calculates the *true* average size of English characters in the
     275 *  specified font as oppposed to the one returned by GetTextMetrics.
     276 *  A convenient variant of DIALOG_GetCharSizeFromDC.
     277 */
     278BOOL Win32Dialog::getCharSize( HFONT hUserFont, SIZE * pSize )
     279{
     280    HDC  hDC = GetDC(0);
     281    BOOL Success = getCharSizeFromDC( hDC, hUserFont, pSize );
     282    ReleaseDC(0, hDC);
     283    return Success;
     284}
     285/***********************************************************************
     286 *           DIALOG_ParseTemplate32
     287 *
     288 * Fill a DLG_TEMPLATE structure from the dialog template, and return
     289 * a pointer to the first control.
     290 */
     291LPCSTR Win32Dialog::parseTemplate( LPCSTR dlgtemplate, DLG_TEMPLATE * result )
     292{
     293    const WORD *p = (const WORD *)dlgtemplate;
     294
     295    result->style = GET_DWORD(p); p += 2;
     296    if (result->style == 0xffff0001)  /* DIALOGEX resource */
     297    {
     298        result->dialogEx = TRUE;
     299        result->helpId   = GET_DWORD(p); p += 2;
     300        result->exStyle  = GET_DWORD(p); p += 2;
     301        result->style    = GET_DWORD(p); p += 2;
     302    }
     303    else
     304    {
     305        result->dialogEx = FALSE;
     306        result->helpId   = 0;
     307        result->exStyle  = GET_DWORD(p); p += 2;
     308    }
     309    result->nbItems = GET_WORD(p); p++;
     310    result->x       = GET_WORD(p); p++;
     311    result->y       = GET_WORD(p); p++;
     312    result->cx      = GET_WORD(p); p++;
     313    result->cy      = GET_WORD(p); p++;
     314
     315    /* Get the menu name */
     316
     317    switch(GET_WORD(p))
     318    {
     319    case 0x0000:
     320        result->menuName = NULL;
     321        p++;
     322        break;
     323    case 0xffff:
     324        result->menuName = (LPCSTR)(UINT)GET_WORD( p + 1 );
     325        p += 2;
     326        break;
     327    default:
     328        result->menuName = (LPCSTR)p;
     329        p += lstrlenW( (LPCWSTR)p ) + 1;
     330        break;
     331    }
     332
     333    /* Get the class name */
     334    switch(GET_WORD(p))
     335    {
     336    case 0x0000:
     337        result->className = (LPCSTR)DIALOG_CLASS_ATOM;
     338        p++;
     339        break;
     340    case 0xffff:
     341        result->className = (LPCSTR)(UINT)GET_WORD( p + 1 );
     342        p += 2;
     343        break;
     344    default:
     345        result->className = (LPCSTR)p;
     346        p += lstrlenW( (LPCWSTR)p ) + 1;
     347        break;
     348    }
     349
     350    /* Get the window caption */
     351
     352    result->caption = (LPCSTR)p;
     353    p += lstrlenW( (LPCWSTR)p ) + 1;
     354
     355    /* Get the font name */
     356
     357    if (result->style & DS_SETFONT)
     358    {
     359        result->pointSize = GET_WORD(p);
     360        p++;
     361        if (result->dialogEx)
     362        {
     363            result->weight = GET_WORD(p); p++;
     364            result->italic = LOBYTE(GET_WORD(p)); p++;
     365        }
     366        else
     367        {
     368            result->weight = FW_DONTCARE;
     369            result->italic = FALSE;
     370        }
     371        result->faceName = (LPCSTR)p;
     372        p += lstrlenW( (LPCWSTR)p ) + 1;
     373    }
     374
     375    /* First control is on dword boundary */
     376    return (LPCSTR)((((int)p) + 3) & ~3);
     377}
     378/***********************************************************************
     379 *           DIALOG_GetControl32
     380 *
     381 * Return the class and text of the control pointed to by ptr,
     382 * fill the header structure and return a pointer to the next control.
     383 */
     384WORD *Win32Dialog::getControl(const WORD *p, DLG_CONTROL_INFO *info, BOOL dialogEx)
     385{
     386    if (dialogEx)
     387    {
     388        info->helpId  = GET_DWORD(p); p += 2;
     389        info->exStyle = GET_DWORD(p); p += 2;
     390        info->style   = GET_DWORD(p); p += 2;
     391    }
     392    else
     393    {
     394        info->helpId  = 0;
     395        info->style   = GET_DWORD(p); p += 2;
     396        info->exStyle = GET_DWORD(p); p += 2;
     397    }
     398    info->x       = GET_WORD(p); p++;
     399    info->y       = GET_WORD(p); p++;
     400    info->cx      = GET_WORD(p); p++;
     401    info->cy      = GET_WORD(p); p++;
     402
     403    if (dialogEx)
     404    {
     405        /* id is a DWORD for DIALOGEX */
     406        info->id = GET_DWORD(p);
     407        p += 2;
     408    }
     409    else
     410    {
     411        info->id = GET_WORD(p);
     412        p++;
     413    }
     414
     415    if (GET_WORD(p) == 0xffff)
     416    {
     417        static const WCHAR class_names[6][10] =
     418        {
     419            { 'B','u','t','t','o','n', },             /* 0x80 */
     420            { 'E','d','i','t', },                     /* 0x81 */
     421            { 'S','t','a','t','i','c', },             /* 0x82 */
     422            { 'L','i','s','t','B','o','x', },         /* 0x83 */
     423            { 'S','c','r','o','l','l','B','a','r', }, /* 0x84 */
     424            { 'C','o','m','b','o','B','o','x', }      /* 0x85 */
     425        };
     426        WORD id = GET_WORD(p+1);
     427        if ((id >= 0x80) && (id <= 0x85))
     428            info->className = (LPCSTR)class_names[id - 0x80];
     429        else
     430        {
     431            info->className = NULL;
     432            dprintf(("Unknown built-in class id %04x\n", id ));
     433        }
     434        p += 2;
     435    }
     436    else
     437    {
     438        info->className = (LPCSTR)p;
     439        p += lstrlenW( (LPCWSTR)p ) + 1;
     440    }
     441
     442    if (GET_WORD(p) == 0xffff)  /* Is it an integer id? */
     443    {
     444            info->windowName = (LPCSTR)(UINT)GET_WORD(p + 1);
     445            p += 2;
     446    }
     447    else
     448    {
     449            info->windowName = (LPCSTR)p;
     450        p += lstrlenW( (LPCWSTR)p ) + 1;
     451    }
     452
     453    if (GET_WORD(p))
     454    {
     455        info->data = (LPVOID)(p + 1);
     456        p += GET_WORD(p) / sizeof(WORD);
     457    }
     458    else info->data = NULL;
     459    p++;
     460
     461    /* Next control is on dword boundary */
     462    return (WORD *)((((int)p) + 3) & ~3);
     463}
     464
     465
     466/***********************************************************************
     467 *           DIALOG_CreateControls
     468 *
     469 * Create the control windows for a dialog.
     470 */
     471BOOL Win32Dialog::createControls(LPCSTR dlgtemplate, HINSTANCE hInst)
     472{
     473    DLG_CONTROL_INFO info;
     474    HWND hwndCtrl, hwndDefButton = 0;
     475    INT items = dlgInfo.nbItems;
     476
     477    while (items--)
     478    {
     479        dlgtemplate = (LPCSTR)getControl( (WORD *)dlgtemplate, &info, dlgInfo.dialogEx );
     480
     481        hwndCtrl = CreateWindowExW( info.exStyle | WS_EX_NOPARENTNOTIFY,
     482                                    (LPCWSTR)info.className,
     483                                    (LPCWSTR)info.windowName,
     484                                    info.style | WS_CHILD,
     485                                    info.x * xUnit / 4,
     486                                    info.y * yUnit / 8,
     487                                    info.cx * xUnit / 4,
     488                                    info.cy * yUnit / 8,
     489                                    getWindowHandle(), (HMENU)info.id,
     490                                    hInst, info.data );
     491
     492        if (!hwndCtrl) return FALSE;
     493
     494            /* Send initialisation messages to the control */
     495        if (hUserFont) ::SendMessageA( hwndCtrl, WM_SETFONT, (WPARAM)hUserFont, 0 );
     496
     497        if (::SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
     498        {
     499            /* If there's already a default push-button, set it back */
     500            /* to normal and use this one instead. */
     501            if (hwndDefButton)
     502                ::SendMessageA( hwndDefButton, BM_SETSTYLE,
     503                                BS_PUSHBUTTON,FALSE );
     504            hwndDefButton = hwndCtrl;
     505            idResult = ::GetWindowWord( hwndCtrl, GWW_ID );
     506        }
     507    }
     508    return TRUE;
     509}
     510/***********************************************************************
     511 *           DEFDLG_Proc
     512 *
     513 * Implementation of DefDlgProc(). Only handle messages that need special
     514 * handling for dialogs.
     515 */
     516LRESULT Win32Dialog::DefDlg_Proc(UINT msg, WPARAM wParam, LPARAM lParam)
     517{
     518    switch(msg)
     519    {
     520    case WM_ERASEBKGND:
     521    {
     522      RECT rect;
     523      int rc;
     524        /*  Since WM_ERASEBKGND may receive either a window dc or a    */
     525        /*  client dc, the area to be erased has to be retrieved from  */
     526        /*  the device context.                    */
     527        rc = GetClipBox( (HDC)wParam, &rect );
     528        if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
     529            FillRect( (HDC)wParam, &rect, windowClass->getBackgroundBrush());
     530            return 1;
     531    }
     532        case WM_NCDESTROY:
     533              /* Free dialog heap (if created) */
     534#if 0   
     535            if (dlgInfo->hDialogHeap)
     536            {
     537                GlobalUnlock16(dlgInfo->hDialogHeap);
     538                GlobalFree16(dlgInfo->hDialogHeap);
     539                    dlgInfo->hDialogHeap = 0;
     540            }
     541#endif
     542              /* Delete font */
     543            if (hUserFont)
     544            {
     545                DeleteObject( hUserFont );
     546                hUserFont = 0;
     547            }
     548
     549              /* Delete menu */
     550            if (hMenu)
     551            {           
     552                    DestroyMenu( hMenu );
     553                    hMenu = 0;
     554            }
     555
     556        /* Delete window procedure */
     557        Win32DlgProc = 0;
     558        dialogFlags |= DF_END;  /* just in case */
     559
     560              /* Window clean-up */
     561            return DefWindowProcA(msg, wParam, lParam );
     562
     563        case WM_SHOWWINDOW:
     564            if (!wParam) saveFocus();
     565            return DefWindowProcA(msg, wParam, lParam );
     566
     567        case WM_ACTIVATE:
     568            if (wParam) {
     569                    restoreFocus();
     570            }
     571            else    saveFocus();
     572            return 0;
     573
     574        case WM_SETFOCUS:
     575            restoreFocus();
     576            return 0;
     577
     578    case DM_SETDEFID:
     579        if (dialogFlags & DF_END)
     580            return 1;
     581
     582        setDefButton(wParam ? GetDlgItem( getWindowHandle(), wParam ) : 0 );
     583        return 1;
     584
     585    case DM_GETDEFID:
     586    {
     587        HWND hwndDefId;
     588        if (dialogFlags & DF_END) return 0;
     589        if (idResult)
     590            return MAKELONG( idResult, DC_HASDEFID );
     591        if ((hwndDefId = findDefButton()))
     592            return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
     593
     594            return 0;
     595    }
     596
     597        case WM_NEXTDLGCTL:
     598        {
     599        HWND hwndDest = (HWND)wParam;
     600        if (!lParam)
     601            hwndDest = GetNextDlgTabItem(getWindowHandle(), GetFocus(), wParam);
     602        if (hwndDest) setFocus( hwndDest );
     603        setDefButton( hwndDest );
     604        return 0;
     605    }
     606
     607    case WM_ENTERMENULOOP:
     608    case WM_LBUTTONDOWN:
     609    case WM_NCLBUTTONDOWN:
     610    {
     611        HWND hwndCurFocus = GetFocus();
     612        if (hwndCurFocus)
     613        {
     614#if 0
     615            WND *wnd = WIN_FindWndPtr( hwndFocus );
     616
     617            if( wnd )
     618            {
     619                /* always make combo box hide its listbox control */
     620                if( WIDGETS_IsControl( wnd, BIC32_COMBO ) )
     621                    SendMessageA( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 );
     622                else
     623                if( WIDGETS_IsControl( wnd, BIC32_EDIT ) &&
     624                    WIDGETS_IsControl( wnd->parent, BIC32_COMBO ))
     625                    SendMessageA(CB_SHOWDROPDOWN, FALSE, 0 );
     626            }
     627#endif
     628        }
     629            return DefWindowProcA( msg, wParam, lParam );
     630    }
     631
     632        case WM_GETFONT:
     633        return hUserFont;
     634
     635    case WM_CLOSE:
     636        PostMessageA(WM_COMMAND, IDCANCEL, (LPARAM)GetDlgItem( getWindowHandle(), IDCANCEL ) );
     637        return 0;
     638
     639    case WM_NOTIFYFORMAT:
     640            return DefWindowProcA(msg, wParam, lParam );
     641    }
     642    return 0;
     643}
     644//******************************************************************************
     645//******************************************************************************
     646LRESULT Win32Dialog::DefDlgProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
     647{
     648    BOOL result = FALSE;
     649
     650    msgResult = 0;
     651
     652    if (Win32DlgProc) {      /* Call dialog procedure */
     653        result = Win32DlgProc(getWindowHandle(), Msg, wParam, lParam);
     654    }
     655
     656    if (!result && IsWindow())
     657    {
     658        /* callback didn't process this message */
     659        switch(Msg)
     660        {
     661            case WM_ERASEBKGND:
     662            case WM_SHOWWINDOW:
     663            case WM_ACTIVATE:
     664            case WM_SETFOCUS:
     665            case DM_SETDEFID:
     666            case DM_GETDEFID:
     667            case WM_NEXTDLGCTL:
     668            case WM_GETFONT:
     669            case WM_CLOSE:
     670            case WM_NCDESTROY:
     671            case WM_ENTERMENULOOP:
     672            case WM_LBUTTONDOWN:
     673            case WM_NCLBUTTONDOWN:
     674                 return DefDlg_Proc(Msg, (WPARAM)wParam, lParam);
     675
     676            case WM_INITDIALOG:
     677            case WM_VKEYTOITEM:
     678            case WM_COMPAREITEM:
     679            case WM_CHARTOITEM:
     680                 break;
     681
     682            default:
     683                 return DefWindowProcA(Msg, wParam, lParam );
     684        }
     685    }
     686    return DefDlg_Epilog(Msg, result);
     687}
     688//******************************************************************************
     689//******************************************************************************
     690LRESULT Win32Dialog::DefDlgProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
     691{
     692    BOOL result = FALSE;
     693
     694    msgResult = 0;
     695
     696    if (Win32DlgProc) {      /* Call dialog procedure */
     697        result = Win32DlgProc(getWindowHandle(), Msg, wParam, lParam);
     698    }
     699
     700    if (!result && IsWindow())
     701    {
     702        /* callback didn't process this message */
     703        switch(Msg)
     704        {
     705            case WM_ERASEBKGND:
     706            case WM_SHOWWINDOW:
     707            case WM_ACTIVATE:
     708            case WM_SETFOCUS:
     709            case DM_SETDEFID:
     710            case DM_GETDEFID:
     711            case WM_NEXTDLGCTL:
     712            case WM_GETFONT:
     713            case WM_CLOSE:
     714            case WM_NCDESTROY:
     715            case WM_ENTERMENULOOP:
     716            case WM_LBUTTONDOWN:
     717            case WM_NCLBUTTONDOWN:
     718                 return DefDlg_Proc(Msg, (WPARAM)wParam, lParam);
     719
     720            case WM_INITDIALOG:
     721            case WM_VKEYTOITEM:
     722            case WM_COMPAREITEM:
     723            case WM_CHARTOITEM:
     724                 break;
     725
     726            default:
     727                 return DefWindowProcW(Msg, wParam, lParam );
     728        }
     729    }
     730    return DefDlg_Epilog(Msg, result);
     731}
     732/***********************************************************************
     733 *           DEFDLG_Epilog
     734 */
     735LRESULT Win32Dialog::DefDlg_Epilog(UINT msg, BOOL fResult)
     736{
     737    /* see SDK 3.1 */
     738    if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
     739             msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
     740         msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
     741         msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
     742        return fResult;
     743
     744    return msgResult;
     745}
     746/***********************************************************************
     747 *           DEFDLG_SetFocus
     748 *
     749 * Set the focus to a control of the dialog, selecting the text if
     750 * the control is an edit dialog.
     751 */
     752void Win32Dialog::setFocus(HWND hwndCtrl )
     753{
     754    HWND hwndPrev = GetFocus();
     755
     756    if (IsChild( hwndPrev ))
     757    {
     758        if (::SendMessageA( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
     759            ::SendMessageA( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
     760    }
     761    if (::SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
     762        ::SendMessageA(hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
     763    SetFocus( hwndCtrl );
     764}
     765
     766
     767/***********************************************************************
     768 *           DEFDLG_SaveFocus
     769 */
     770BOOL Win32Dialog::saveFocus()
     771{
     772    HWND hwndCurrentFocus = GetFocus();
     773
     774    if (!hwndCurrentFocus || !IsChild( hwndCurrentFocus )) return FALSE;
     775
     776    hwndFocus = hwndCurrentFocus;
     777      /* Remove default button */
     778    return TRUE;
     779}
     780
     781
     782/***********************************************************************
     783 *           DEFDLG_RestoreFocus
     784 */
     785BOOL Win32Dialog::restoreFocus()
     786{
     787    if (!hwndFocus || IsIconic()) return FALSE;
     788
     789    if (!::IsWindow( hwndFocus )) return FALSE;
     790
     791    /* Don't set the focus back to controls if EndDialog is already called.*/
     792    if (!(dialogFlags & DF_END))
     793       setFocus(hwndFocus);
     794
     795    /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
     796       sometimes losing focus when receiving WM_SETFOCUS messages. */
     797    return TRUE;
     798}
     799
     800
     801/***********************************************************************
     802 *           DEFDLG_FindDefButton
     803 *
     804 * Find the current default push-button.
     805 */
     806HWND Win32Dialog::findDefButton()
     807{
     808    HWND hwndChild = GetWindow( GW_CHILD );
     809    while (hwndChild)
     810    {
     811        if (::SendMessageA( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
     812            break;
     813        hwndChild = ::GetWindow( hwndChild, GW_HWNDNEXT );
     814    }
     815    return hwndChild;
     816}
     817
     818
     819/***********************************************************************
     820 *           DEFDLG_SetDefButton
     821 *
     822 * Set the new default button to be hwndNew.
     823 */
     824BOOL Win32Dialog::setDefButton(HWND hwndNew )
     825{
     826    if (hwndNew &&
     827        !(::SendMessageA(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
     828        return FALSE;  /* Destination is not a push button */
     829
     830    if (idResult)  /* There's already a default pushbutton */
     831    {
     832        HWND hwndOld = GetDlgItem( getWindowHandle(), idResult );
     833        if (::SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
     834            ::SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
     835    }
     836    if (hwndNew)
     837    {
     838        ::SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
     839        idResult = GetDlgCtrlID( hwndNew );
     840    }
     841    else idResult = 0;
     842    return TRUE;
    28843}
    29844//******************************************************************************
     
    76891//******************************************************************************
    77892//******************************************************************************
     893BOOL DIALOG_Register()
     894{
     895    WNDCLASSA wndClass;
     896
     897    if (GlobalFindAtomA(DIALOG_CLASS_NAME)) return FALSE;
     898
     899    ZeroMemory(&wndClass,sizeof(WNDCLASSA));
     900    wndClass.style         = CS_GLOBALCLASS | CS_SAVEBITS;
     901    wndClass.lpfnWndProc   = (WNDPROC)DefDlgProcA;
     902    wndClass.cbClsExtra    = 0;
     903    wndClass.cbWndExtra    = 0;
     904    wndClass.hCursor       = (HCURSOR)IDC_ARROWA;
     905    wndClass.hbrBackground = LTGRAY_BRUSH;
     906    wndClass.lpszClassName = DIALOG_CLASS_NAME;
     907
     908    return RegisterClassA(&wndClass);
     909}
     910//******************************************************************************
     911//******************************************************************************
     912BOOL DIALOG_Unregister()
     913{
     914    if (GlobalFindAtomA(DIALOG_CLASS_NAME))
     915            return UnregisterClassA(DIALOG_CLASS_NAME,(HINSTANCE)NULL);
     916    else    return FALSE;
     917}
     918//******************************************************************************
     919//******************************************************************************
     920BOOL Win32Dialog::fInitialized = FALSE;
     921int  Win32Dialog::xBaseUnit    = 0;
     922int  Win32Dialog::yBaseUnit    = 0;
Note: See TracChangeset for help on using the changeset viewer.