| /* |
| * Dialog functions |
| * |
| * Copyright 1993, 1994 Alexandre Julliard |
| * |
| */ |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include "windows.h" |
| #include "dialog.h" |
| #include "win.h" |
| #include "ldt.h" |
| #include "stackframe.h" |
| #include "user.h" |
| #include "message.h" |
| #include "stddebug.h" |
| /* #define DEBUG_DIALOG */ |
| #include "debug.h" |
| |
| /* Dialog base units */ |
| WORD xBaseUnit = 0, yBaseUnit = 0; |
| |
| |
| /*********************************************************************** |
| * DIALOG_Init |
| * |
| * Initialisation of the dialog manager. |
| */ |
| BOOL DIALOG_Init() |
| { |
| TEXTMETRIC tm; |
| HDC hdc; |
| |
| /* Calculate the dialog base units */ |
| |
| if (!(hdc = GetDC( 0 ))) return FALSE; |
| GetTextMetrics( hdc, &tm ); |
| ReleaseDC( 0, hdc ); |
| xBaseUnit = tm.tmAveCharWidth; |
| yBaseUnit = tm.tmHeight; |
| |
| /* Dialog units are based on a proportional system font */ |
| /* so we adjust them a bit for a fixed font. */ |
| if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) xBaseUnit = xBaseUnit * 5 / 4; |
| |
| dprintf_dialog( stddeb, "DIALOG_Init: base units = %d,%d\n", |
| xBaseUnit, yBaseUnit ); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_GetFirstTabItem |
| * |
| * Return the first item of the dialog that has the WS_TABSTOP style. |
| */ |
| HWND DIALOG_GetFirstTabItem( HWND hwndDlg ) |
| { |
| WND *pWnd = WIN_FindWndPtr( hwndDlg ); |
| for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) |
| if (pWnd->dwStyle & WS_TABSTOP) return pWnd->hwndSelf; |
| return 0; |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_GetControl |
| * |
| * Return the class and text of the control pointed to by ptr, |
| * and return a pointer to the next control. |
| */ |
| static SEGPTR DIALOG_GetControl( SEGPTR ptr, SEGPTR *class, SEGPTR *text ) |
| { |
| unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN( ptr ); |
| unsigned char *p = base; |
| |
| p += 14; /* size of control header */ |
| |
| if (*p & 0x80) |
| { |
| *class = MAKEINTRESOURCE( *p ); |
| p++; |
| } |
| else |
| { |
| *class = ptr + (WORD)(p - base); |
| p += strlen(p) + 1; |
| } |
| |
| if (*p == 0xff) |
| { |
| /* Integer id, not documented (?). Only works for SS_ICON controls */ |
| *text = MAKEINTRESOURCE( p[1] + 256 * p[2] ); |
| p += 4; |
| } |
| else |
| { |
| *text = ptr + (WORD)(p - base); |
| p += strlen(p) + 2; |
| } |
| return ptr + (WORD)(p - base); |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_ParseTemplate |
| * |
| * Fill a DLGTEMPLATE structure from the dialog template, and return |
| * a pointer to the first control. |
| */ |
| static SEGPTR DIALOG_ParseTemplate( SEGPTR template, DLGTEMPLATE * result ) |
| { |
| unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN(template); |
| unsigned char * p = base; |
| |
| result->header = *(DLGTEMPLATEHEADER *)p; |
| p += 13; |
| |
| /* Get the menu name */ |
| |
| if (*p == 0xff) |
| { |
| result->menuName = MAKEINTRESOURCE( p[1] + 256 * p[2] ); |
| p += 3; |
| } |
| else if (*p) |
| { |
| result->menuName = template + (WORD)(p - base); |
| p += strlen(p) + 1; |
| } |
| else |
| { |
| result->menuName = 0; |
| p++; |
| } |
| |
| /* Get the class name */ |
| |
| if (*p) result->className = template + (WORD)(p - base); |
| else result->className = DIALOG_CLASS_ATOM; |
| p += strlen(p) + 1; |
| |
| /* Get the window caption */ |
| |
| result->caption = template + (WORD)(p - base); |
| p += strlen(p) + 1; |
| |
| /* Get the font name */ |
| |
| if (result->header.style & DS_SETFONT) |
| { |
| result->pointSize = *(WORD *)p; |
| p += sizeof(WORD); |
| result->faceName = template + (WORD)(p - base); |
| p += strlen(p) + 1; |
| } |
| |
| return template + (WORD)(p - base); |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_DisplayTemplate |
| */ |
| static void DIALOG_DisplayTemplate( DLGTEMPLATE * result ) |
| { |
| dprintf_dialog(stddeb, "DIALOG %d, %d, %d, %d\n", result->header.x, result->header.y, |
| result->header.cx, result->header.cy ); |
| dprintf_dialog(stddeb, " STYLE %08lx\n", result->header.style ); |
| dprintf_dialog( stddeb, " CAPTION '%s'\n", |
| (char *)PTR_SEG_TO_LIN(result->caption) ); |
| |
| if (HIWORD(result->className)) |
| dprintf_dialog( stddeb, " CLASS '%s'\n", |
| (char *)PTR_SEG_TO_LIN(result->className) ); |
| else |
| dprintf_dialog( stddeb, " CLASS #%d\n", LOWORD(result->className) ); |
| |
| if (HIWORD(result->menuName)) |
| dprintf_dialog( stddeb, " MENU '%s'\n", |
| (char *)PTR_SEG_TO_LIN(result->menuName) ); |
| else if (LOWORD(result->menuName)) |
| dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) ); |
| |
| if (result->header.style & DS_SETFONT) |
| dprintf_dialog( stddeb, " FONT %d,'%s'\n", result->pointSize, |
| (char *)PTR_SEG_TO_LIN(result->faceName) ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialog (USER.89) |
| */ |
| HWND CreateDialog( HINSTANCE hInst, SEGPTR dlgTemplate, |
| HWND owner, DLGPROC dlgProc ) |
| { |
| return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogParam (USER.241) |
| */ |
| HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate, |
| HWND owner, DLGPROC dlgProc, LPARAM param ) |
| { |
| HWND hwnd = 0; |
| HRSRC hRsrc; |
| HGLOBAL hmem; |
| SEGPTR data; |
| |
| dprintf_dialog(stddeb, "CreateDialogParam: %04x,%08lx,%04x,%08lx,%ld\n", |
| hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param ); |
| |
| if (!(hRsrc = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0; |
| if (!(hmem = LoadResource( hInst, hRsrc ))) return 0; |
| if (!(data = WIN16_LockResource( hmem ))) hwnd = 0; |
| else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param); |
| FreeResource( hmem ); |
| return hwnd; |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogIndirect (USER.219) |
| */ |
| HWND CreateDialogIndirect( HINSTANCE hInst, SEGPTR dlgTemplate, |
| HWND owner, DLGPROC dlgProc ) |
| { |
| return CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogIndirectParam (USER.242) |
| */ |
| HWND CreateDialogIndirectParam( HINSTANCE hInst, SEGPTR dlgTemplate, |
| HWND owner, DLGPROC dlgProc, LPARAM param ) |
| { |
| HMENU hMenu = 0; |
| HFONT hFont = 0; |
| HWND hwnd, hwndCtrl; |
| RECT rect; |
| WND * wndPtr; |
| int i; |
| DLGTEMPLATE template; |
| SEGPTR headerPtr; |
| DIALOGINFO * dlgInfo; |
| DWORD exStyle = 0; |
| WORD xUnit = xBaseUnit; |
| WORD yUnit = yBaseUnit; |
| |
| /* Parse dialog template */ |
| |
| if (!dlgTemplate) return 0; |
| headerPtr = DIALOG_ParseTemplate( dlgTemplate, &template ); |
| if (debugging_dialog) DIALOG_DisplayTemplate( &template ); |
| |
| /* Load menu */ |
| |
| if (template.menuName) hMenu = LoadMenu( hInst, template.menuName ); |
| |
| /* Create custom font if needed */ |
| |
| if (template.header.style & DS_SETFONT) |
| { |
| /* The font height must be negative as it is a point size */ |
| /* (see CreateFont() documentation in the Windows SDK). */ |
| hFont = CreateFont( -template.pointSize, 0, 0, 0, FW_DONTCARE, |
| FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, |
| DEFAULT_QUALITY, FF_DONTCARE, |
| (LPSTR)PTR_SEG_TO_LIN(template.faceName) ); |
| if (hFont) |
| { |
| TEXTMETRIC tm; |
| HFONT oldFont; |
| HDC hdc; |
| |
| hdc = GetDC(0); |
| oldFont = SelectObject( hdc, hFont ); |
| GetTextMetrics( hdc, &tm ); |
| SelectObject( hdc, oldFont ); |
| ReleaseDC( 0, hdc ); |
| xUnit = tm.tmAveCharWidth; |
| yUnit = tm.tmHeight; |
| if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) |
| xBaseUnit = xBaseUnit * 5 / 4; /* See DIALOG_Init() */ |
| } |
| } |
| |
| /* Create dialog main window */ |
| |
| rect.left = rect.top = 0; |
| rect.right = template.header.cx * xUnit / 4; |
| rect.bottom = template.header.cy * yUnit / 8; |
| if (template.header.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME; |
| AdjustWindowRectEx( &rect, template.header.style, |
| hMenu ? TRUE : FALSE , exStyle ); |
| rect.right -= rect.left; |
| rect.bottom -= rect.top; |
| |
| if ((INT)template.header.x == CW_USEDEFAULT) |
| rect.left = rect.top = CW_USEDEFAULT; |
| else |
| { |
| rect.left += template.header.x * xUnit / 4; |
| rect.top += template.header.y * yUnit / 8; |
| if (!(template.header.style & DS_ABSALIGN)) |
| ClientToScreen( owner, (POINT *)&rect ); |
| } |
| |
| hwnd = CreateWindowEx( exStyle, template.className, template.caption, |
| template.header.style & ~WS_VISIBLE, |
| rect.left, rect.top, rect.right, rect.bottom, |
| owner, hMenu, hInst, (SEGPTR)0 ); |
| if (!hwnd) |
| { |
| if (hFont) DeleteObject( hFont ); |
| if (hMenu) DestroyMenu( hMenu ); |
| return 0; |
| } |
| wndPtr = WIN_FindWndPtr( hwnd ); |
| |
| /* Purge junk from system menu */ |
| /* FIXME: this doesn't belong here */ |
| |
| DeleteMenu(wndPtr->hSysMenu,SC_SIZE,MF_BYCOMMAND); |
| if (!(wndPtr->dwStyle & WS_MAXIMIZEBOX) ) |
| { |
| DeleteMenu(wndPtr->hSysMenu,SC_MAXIMIZE,MF_BYCOMMAND); |
| if( !(wndPtr->dwStyle & WS_MINIMIZEBOX) ) |
| { |
| DeleteMenu(wndPtr->hSysMenu,SC_MINIMIZE,MF_BYCOMMAND); |
| DeleteMenu(wndPtr->hSysMenu,SC_RESTORE,MF_BYCOMMAND); |
| } |
| } |
| else |
| if (!(wndPtr->dwStyle & WS_MINIMIZEBOX) ) |
| DeleteMenu(wndPtr->hSysMenu,SC_MINIMIZE,MF_BYCOMMAND); |
| |
| /* Create control windows */ |
| |
| dprintf_dialog(stddeb, " BEGIN\n" ); |
| |
| dlgInfo = (DIALOGINFO *)wndPtr->wExtra; |
| dlgInfo->msgResult = 0; /* This is used to store the default button id */ |
| dlgInfo->hDialogHeap = 0; |
| |
| for (i = 0; i < template.header.nbItems; i++) |
| { |
| DLGCONTROLHEADER *header; |
| SEGPTR className, winName; |
| HWND hwndDefButton = 0; |
| char buffer[10]; |
| |
| header = (DLGCONTROLHEADER *)PTR_SEG_TO_LIN( headerPtr ); |
| headerPtr = DIALOG_GetControl( headerPtr, &className, &winName ); |
| |
| if (!HIWORD(className)) |
| { |
| switch(LOWORD(className)) |
| { |
| case 0x80: strcpy( buffer, "BUTTON" ); break; |
| case 0x81: strcpy( buffer, "EDIT" ); break; |
| case 0x82: strcpy( buffer, "STATIC" ); break; |
| case 0x83: strcpy( buffer, "LISTBOX" ); break; |
| case 0x84: strcpy( buffer, "SCROLLBAR" ); break; |
| case 0x85: strcpy( buffer, "COMBOBOX" ); break; |
| default: buffer[0] = '\0'; break; |
| } |
| className = MAKE_SEGPTR(buffer); |
| } |
| |
| if (HIWORD(className)) |
| dprintf_dialog(stddeb, " %s ", (char*)PTR_SEG_TO_LIN(className)); |
| else dprintf_dialog(stddeb, " %04x ", LOWORD(className) ); |
| if (HIWORD(winName)) |
| dprintf_dialog(stddeb,"'%s'", (char *)PTR_SEG_TO_LIN(winName) ); |
| else dprintf_dialog(stddeb,"%04x", LOWORD(winName) ); |
| |
| dprintf_dialog(stddeb," %d, %d, %d, %d, %d, %08lx\n", |
| header->id, header->x, header->y, |
| header->cx, header->cy, header->style ); |
| |
| if (HIWORD(className) && |
| !strcmp( (char *)PTR_SEG_TO_LIN(className), "EDIT") && |
| ((header->style & DS_LOCALEDIT) != DS_LOCALEDIT)) |
| { |
| if (!dlgInfo->hDialogHeap) |
| { |
| dlgInfo->hDialogHeap = GlobalAlloc(GMEM_FIXED, 0x10000); |
| if (!dlgInfo->hDialogHeap) |
| { |
| fprintf(stderr,"CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n"); |
| continue; |
| } |
| LocalInit(dlgInfo->hDialogHeap, 0, 0xffff); |
| } |
| hwndCtrl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, className, winName, |
| header->style | WS_CHILD, |
| header->x * xUnit / 4, |
| header->y * yUnit / 8, |
| header->cx * xUnit / 4, |
| header->cy * yUnit / 8, |
| hwnd, (HMENU)header->id, |
| dlgInfo->hDialogHeap, (SEGPTR)0 ); |
| } |
| else |
| { |
| hwndCtrl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, className, winName, |
| header->style | WS_CHILD, |
| header->x * xUnit / 4, |
| header->y * yUnit / 8, |
| header->cx * xUnit / 4, |
| header->cy * yUnit / 8, |
| hwnd, (HMENU)header->id, |
| hInst, (SEGPTR)0 ); |
| } |
| |
| /* Make the control last one in Z-order, so that controls remain |
| in the order in which they were created */ |
| SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0, |
| SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE ); |
| |
| /* Send initialisation messages to the control */ |
| if (hFont) SendMessage( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 ); |
| if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON) |
| { |
| /* If there's already a default push-button, set it back */ |
| /* to normal and use this one instead. */ |
| if (hwndDefButton) |
| SendMessage( hwndDefButton, BM_SETSTYLE, BS_PUSHBUTTON, FALSE); |
| hwndDefButton = hwndCtrl; |
| dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID ); |
| } |
| } |
| |
| dprintf_dialog(stddeb, " END\n" ); |
| |
| /* Initialise dialog extra data */ |
| |
| dlgInfo->dlgProc = dlgProc; |
| dlgInfo->hUserFont = hFont; |
| dlgInfo->hMenu = hMenu; |
| dlgInfo->xBaseUnit = xUnit; |
| dlgInfo->yBaseUnit = yUnit; |
| dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd ); |
| |
| /* Send initialisation messages and set focus */ |
| |
| if (dlgInfo->hUserFont) |
| SendMessage( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 ); |
| if (SendMessage( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param )) |
| SetFocus( dlgInfo->hwndFocus ); |
| if (template.header.style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW); |
| return hwnd; |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_DoDialogBox |
| */ |
| int DIALOG_DoDialogBox( HWND hwnd, HWND owner ) |
| { |
| WND * wndPtr; |
| DIALOGINFO * dlgInfo; |
| HANDLE msgHandle; |
| MSG* lpmsg; |
| int retval; |
| |
| /* Owner must be a top-level window */ |
| owner = WIN_GetTopParent( owner ); |
| if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1; |
| if (!(msgHandle = USER_HEAP_ALLOC( sizeof(MSG) ))) return -1; |
| lpmsg = (MSG *) USER_HEAP_LIN_ADDR( msgHandle ); |
| dlgInfo = (DIALOGINFO *)wndPtr->wExtra; |
| EnableWindow( owner, FALSE ); |
| ShowWindow( hwnd, SW_SHOW ); |
| |
| while (MSG_InternalGetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(msgHandle), hwnd, owner, |
| MSGF_DIALOGBOX, PM_REMOVE, |
| !(wndPtr->dwStyle & DS_NOIDLEMSG) )) |
| { |
| if (!IsDialogMessage( hwnd, lpmsg)) |
| { |
| TranslateMessage( lpmsg ); |
| DispatchMessage( lpmsg ); |
| } |
| if (dlgInfo->fEnd) break; |
| } |
| retval = dlgInfo->msgResult; |
| DestroyWindow( hwnd ); |
| USER_HEAP_FREE( msgHandle ); |
| EnableWindow( owner, TRUE ); |
| return retval; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBox (USER.87) |
| */ |
| INT DialogBox( HINSTANCE hInst, SEGPTR dlgTemplate, |
| HWND owner, DLGPROC dlgProc ) |
| { |
| return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxParam (USER.239) |
| */ |
| INT DialogBoxParam( HINSTANCE hInst, SEGPTR dlgTemplate, |
| HWND owner, DLGPROC dlgProc, LPARAM param ) |
| { |
| HWND hwnd; |
| |
| dprintf_dialog(stddeb, "DialogBoxParam: %04x,%08lx,%04x,%08lx,%ld\n", |
| hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param ); |
| hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param ); |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxIndirect (USER.218) |
| */ |
| INT DialogBoxIndirect( HINSTANCE hInst, HANDLE dlgTemplate, |
| HWND owner, DLGPROC dlgProc ) |
| { |
| return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxIndirectParam (USER.240) |
| */ |
| INT DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate, |
| HWND owner, DLGPROC dlgProc, LPARAM param ) |
| { |
| HWND hwnd; |
| SEGPTR ptr; |
| |
| if (!(ptr = (SEGPTR)WIN16_GlobalLock( dlgTemplate ))) return -1; |
| hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param ); |
| GlobalUnlock( dlgTemplate ); |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * EndDialog (USER.88) |
| */ |
| BOOL EndDialog( HWND hwnd, INT retval ) |
| { |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra; |
| dlgInfo->msgResult = retval; |
| dlgInfo->fEnd = TRUE; |
| dprintf_dialog(stddeb, "EndDialog: %04x %d\n", hwnd, retval ); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * IsDialogMessage (USER.90) |
| */ |
| BOOL IsDialogMessage( HWND hwndDlg, LPMSG msg ) |
| { |
| WND * wndPtr; |
| int dlgCode; |
| |
| if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return FALSE; |
| if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) return FALSE; |
| |
| /* Only the key messages get special processing */ |
| if ((msg->message != WM_KEYDOWN) && |
| (msg->message != WM_SYSCHAR) && |
| (msg->message != WM_CHAR)) |
| return FALSE; |
| |
| dlgCode = SendMessage( msg->hwnd, WM_GETDLGCODE, 0, 0 ); |
| if (dlgCode & DLGC_WANTMESSAGE) |
| { |
| DispatchMessage( msg ); |
| return TRUE; |
| } |
| |
| switch(msg->message) |
| { |
| case WM_KEYDOWN: |
| if (dlgCode & DLGC_WANTALLKEYS) break; |
| switch(msg->wParam) |
| { |
| case VK_TAB: |
| if (!(dlgCode & DLGC_WANTTAB)) |
| { |
| SendMessage( hwndDlg, WM_NEXTDLGCTL, |
| (GetKeyState(VK_SHIFT) & 0x80), 0 ); |
| return TRUE; |
| } |
| break; |
| |
| case VK_RIGHT: |
| case VK_DOWN: |
| if (!(dlgCode & DLGC_WANTARROWS)) |
| { |
| SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),FALSE)); |
| return TRUE; |
| } |
| break; |
| |
| case VK_LEFT: |
| case VK_UP: |
| if (!(dlgCode & DLGC_WANTARROWS)) |
| { |
| SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),TRUE)); |
| return TRUE; |
| } |
| break; |
| |
| case VK_ESCAPE: |
| #ifdef WINELIB32 |
| SendMessage( hwndDlg, WM_COMMAND, |
| MAKEWPARAM( IDCANCEL, 0 ), |
| (LPARAM)GetDlgItem(hwndDlg,IDCANCEL) ); |
| #else |
| SendMessage( hwndDlg, WM_COMMAND, IDCANCEL, |
| MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 )); |
| #endif |
| break; |
| |
| case VK_RETURN: |
| { |
| DWORD dw = SendMessage( hwndDlg, DM_GETDEFID, 0, 0 ); |
| if (HIWORD(dw) == DC_HASDEFID) |
| #ifdef WINELIB32 |
| SendMessage( hwndDlg, WM_COMMAND, |
| MAKEWPARAM( LOWORD(dw), BN_CLICKED ), |
| (LPARAM)GetDlgItem( hwndDlg, LOWORD(dw) ) ); |
| else |
| SendMessage( hwndDlg, WM_COMMAND, |
| MAKEWPARAM( IDOK, 0 ), |
| (LPARAM)GetDlgItem(hwndDlg,IDOK) ); |
| #else |
| SendMessage( hwndDlg, WM_COMMAND, LOWORD(dw), |
| MAKELPARAM( GetDlgItem( hwndDlg, LOWORD(dw) ), |
| BN_CLICKED )); |
| else |
| SendMessage( hwndDlg, WM_COMMAND, IDOK, |
| MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 )); |
| #endif |
| } |
| break; |
| |
| default: |
| TranslateMessage( msg ); |
| } |
| break; /* case WM_KEYDOWN */ |
| |
| |
| case WM_CHAR: |
| if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break; |
| break; |
| |
| case WM_SYSCHAR: |
| if (dlgCode & DLGC_WANTALLKEYS) break; |
| break; |
| } |
| |
| /* If we get here, the message has not been treated specially */ |
| /* and can be sent to its destination window. */ |
| DispatchMessage( msg ); |
| return TRUE; |
| } |
| |
| |
| /**************************************************************** |
| * GetDlgCtrlID (USER.277) |
| */ |
| int GetDlgCtrlID( HWND hwnd ) |
| { |
| WND *wndPtr = WIN_FindWndPtr(hwnd); |
| if (wndPtr) return wndPtr->wIDmenu; |
| else return 0; |
| } |
| |
| |
| /*********************************************************************** |
| * GetDlgItem (USER.91) |
| */ |
| HWND GetDlgItem( HWND hwndDlg, WORD id ) |
| { |
| WND *pWnd; |
| |
| if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0; |
| for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) |
| if (pWnd->wIDmenu == id) return pWnd->hwndSelf; |
| return 0; |
| } |
| |
| |
| /******************************************************************* |
| * SendDlgItemMessage (USER.101) |
| */ |
| LRESULT SendDlgItemMessage(HWND hwnd, INT id, UINT msg, WPARAM wParam, LPARAM lParam) |
| { |
| HWND hwndCtrl = GetDlgItem( hwnd, id ); |
| if (hwndCtrl) return SendMessage( hwndCtrl, msg, wParam, lParam ); |
| else return 0; |
| } |
| |
| |
| /******************************************************************* |
| * SetDlgItemText (USER.92) |
| */ |
| void SetDlgItemText( HWND hwnd, WORD id, SEGPTR lpString ) |
| { |
| SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetDlgItemText (USER.93) |
| */ |
| int GetDlgItemText( HWND hwnd, WORD id, SEGPTR str, WORD max ) |
| { |
| return (int)SendDlgItemMessage( hwnd, id, WM_GETTEXT, max, (DWORD)str ); |
| } |
| |
| |
| /******************************************************************* |
| * SetDlgItemInt (USER.94) |
| */ |
| void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned ) |
| { |
| char str[20]; |
| |
| if (fSigned) sprintf( str, "%d", (int)value ); |
| else sprintf( str, "%u", value ); |
| SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(str) ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetDlgItemInt (USER.95) |
| */ |
| WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned ) |
| { |
| char str[30]; |
| long result = 0; |
| |
| if (translated) *translated = FALSE; |
| if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, 30, (LPARAM)MAKE_SEGPTR(str) )) |
| { |
| char * endptr; |
| result = strtol( str, &endptr, 10 ); |
| if (endptr && (endptr != str)) /* Conversion was successful */ |
| { |
| if (fSigned) |
| { |
| if ((result < -32767) || (result > 32767)) result = 0; |
| else if (translated) *translated = TRUE; |
| } |
| else |
| { |
| if ((result < 0) || (result > 65535)) result = 0; |
| else if (translated) *translated = TRUE; |
| } |
| } |
| } |
| return (WORD)result; |
| } |
| |
| |
| /*********************************************************************** |
| * CheckDlgButton (USER.97) |
| */ |
| BOOL CheckDlgButton( HWND hwnd, INT id, UINT check ) |
| { |
| SendDlgItemMessage( hwnd, id, BM_SETCHECK, check, 0 ); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * IsDlgButtonChecked (USER.98) |
| */ |
| WORD IsDlgButtonChecked( HWND hwnd, WORD id ) |
| { |
| return (WORD)SendDlgItemMessage( hwnd, id, BM_GETCHECK, 0, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * CheckRadioButton (USER.96) |
| */ |
| BOOL CheckRadioButton( HWND hwndDlg, UINT firstID, UINT lastID, UINT checkID ) |
| { |
| WND *pWnd = WIN_FindWndPtr( hwndDlg ); |
| if (!pWnd) return FALSE; |
| |
| for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) |
| if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID)) break; |
| if (!pWnd) return FALSE; |
| |
| if (pWnd->wIDmenu == lastID) |
| lastID = firstID; /* Buttons are in reverse order */ |
| while (pWnd) |
| { |
| SendMessage(pWnd->hwndSelf, BM_SETCHECK, (pWnd->wIDmenu == checkID),0); |
| if (pWnd->wIDmenu == lastID) break; |
| pWnd = pWnd->next; |
| } |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * GetDialogBaseUnits (USER.243) |
| */ |
| DWORD GetDialogBaseUnits() |
| { |
| return MAKELONG( xBaseUnit, yBaseUnit ); |
| } |
| |
| |
| /*********************************************************************** |
| * MapDialogRect (USER.103) |
| */ |
| void MapDialogRect( HWND hwnd, LPRECT rect ) |
| { |
| DIALOGINFO * dlgInfo; |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| if (!wndPtr) return; |
| dlgInfo = (DIALOGINFO *)wndPtr->wExtra; |
| rect->left = (rect->left * dlgInfo->xBaseUnit) / 4; |
| rect->right = (rect->right * dlgInfo->xBaseUnit) / 4; |
| rect->top = (rect->top * dlgInfo->yBaseUnit) / 8; |
| rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8; |
| } |
| |
| |
| /*********************************************************************** |
| * GetNextDlgGroupItem (USER.227) |
| */ |
| HWND GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious ) |
| { |
| WND *pWnd, *pWndStart, *pWndCtrl, *pWndDlg; |
| |
| if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; |
| if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0; |
| if (pWndCtrl->parent != pWndDlg) return 0; |
| |
| if (!fPrevious && pWndCtrl->next) /* Check if next control is in group */ |
| { |
| if (!(pWndCtrl->next->dwStyle & WS_GROUP)) |
| return pWndCtrl->next->hwndSelf; |
| } |
| |
| /* Now we will have to find the start of the group */ |
| |
| for (pWnd = pWndStart = pWndDlg->child; pWnd; pWnd = pWnd->next) |
| { |
| if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd; /* Start of a group */ |
| if (pWnd == pWndCtrl) break; |
| } |
| |
| if (!pWnd) fprintf(stderr, "GetNextDlgGroupItem: hwnd not in dialog!\n"); |
| |
| /* only case left for forward search: wraparound */ |
| if (!fPrevious) return pWndStart->hwndSelf; |
| |
| pWnd = pWndStart->next; |
| while (pWnd && (pWnd != pWndCtrl)) |
| { |
| if (pWnd->dwStyle & WS_GROUP) break; |
| pWndStart = pWnd; |
| pWnd = pWnd->next; |
| } |
| return pWndStart->hwndSelf; |
| } |
| |
| |
| /*********************************************************************** |
| * GetNextDlgTabItem (USER.228) |
| */ |
| HWND GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious ) |
| { |
| WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg; |
| |
| if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; |
| if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0; |
| if (pWndCtrl->parent != pWndDlg) return 0; |
| |
| pWndLast = pWndCtrl; |
| pWnd = pWndCtrl->next; |
| while (1) |
| { |
| if (!pWnd) pWnd = pWndDlg->child; |
| if (pWnd == pWndCtrl) break; |
| if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE)) |
| { |
| pWndLast = pWnd; |
| if (!fPrevious) break; |
| } |
| pWnd = pWnd->next; |
| } |
| return pWndLast->hwndSelf; |
| } |