| /* | |
| * Dialog functions | |
| * | |
| * Copyright 1993, 1994 Alexandre Julliard | |
| * | |
| static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994"; | |
| */ | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include "windows.h" | |
| #include "dialog.h" | |
| #include "win.h" | |
| #include "user.h" | |
| #include "message.h" | |
| #include "heap.h" | |
| #include "stddebug.h" | |
| /* #define DEBUG_DIALOG */ | |
| #include "debug.h" | |
| /* Dialog base units */ | |
| static 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 ) | |
| { | |
| HWND hwnd; | |
| WND *wndPtr = WIN_FindWndPtr( hwndDlg ); | |
| hwnd = wndPtr->hwndChild; | |
| while(hwnd) | |
| { | |
| wndPtr = WIN_FindWndPtr( hwnd ); | |
| if (wndPtr->dwStyle & WS_TABSTOP) break; | |
| hwnd = wndPtr->hwndNext; | |
| } | |
| return hwnd; | |
| } | |
| /*********************************************************************** | |
| * DIALOG_GetControl | |
| * | |
| * Return the class and text of the control pointed to by ptr, | |
| * and return a pointer to the next control. | |
| */ | |
| static DLGCONTROLHEADER * DIALOG_GetControl( DLGCONTROLHEADER * ptr, | |
| char ** class, char ** text ) | |
| { | |
| unsigned char * p = (unsigned char *)ptr; | |
| p += 14; /* size of control header */ | |
| if (*p & 0x80) | |
| { | |
| switch(*p++) | |
| { | |
| case 0x80: *class = "BUTTON"; break; | |
| case 0x81: *class = "EDIT"; break; | |
| case 0x82: *class = "STATIC"; break; | |
| case 0x83: *class = "LISTBOX"; break; | |
| case 0x84: *class = "SCROLLBAR"; break; | |
| case 0x85: *class = "COMBOBOX"; break; | |
| default: *class = ""; break; | |
| } | |
| } | |
| else | |
| { | |
| *class = p; | |
| p += strlen(p) + 1; | |
| } | |
| if (*p == 0xff) | |
| { | |
| /* Integer id, not documented (?). Only works for SS_ICON controls */ | |
| *text = (char *)MAKEINTRESOURCE( p[1] + 256*p[2] ); | |
| p += 4; | |
| } | |
| else | |
| { | |
| *text = p; | |
| p += strlen(p) + 2; | |
| } | |
| return (DLGCONTROLHEADER *)p; | |
| } | |
| /*********************************************************************** | |
| * DIALOG_ParseTemplate | |
| * | |
| * Fill a DLGTEMPLATE structure from the dialog template, and return | |
| * a pointer to the first control. | |
| */ | |
| static DLGCONTROLHEADER * DIALOG_ParseTemplate( LPCSTR template, | |
| DLGTEMPLATE * result ) | |
| { | |
| unsigned char * p = (unsigned char *)template; | |
| result->header = (DLGTEMPLATEHEADER *)p; | |
| p += 13; | |
| result->menuName = p; | |
| if (*p == 0xff) p += 3; | |
| else p += strlen(p) + 1; | |
| if (*p) result->className = p; | |
| else result->className = DIALOG_CLASS_NAME; | |
| p += strlen(p) + 1; | |
| result->caption = p; | |
| p += strlen(p) + 1; | |
| if (result->header->style & DS_SETFONT) | |
| { | |
| result->pointSize = *(WORD *)p; p += sizeof(WORD); | |
| result->faceName = p; p += strlen(p) + 1; | |
| } | |
| return (DLGCONTROLHEADER *)p; | |
| } | |
| /*********************************************************************** | |
| * 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", result->caption ); | |
| dprintf_dialog(stddeb, " CLASS '%s'\n", result->className ); | |
| if (result->menuName[0] == 0xff) | |
| dprintf_dialog(stddeb, " MENU %d\n", result->menuName[1] + 256*result->menuName[2] ); | |
| else | |
| dprintf_dialog(stddeb, " MENU '%s'\n", result->menuName ); | |
| if (result->header->style & DS_SETFONT) | |
| dprintf_dialog(stddeb, " FONT %d,'%s'\n", result->pointSize, result->faceName ); | |
| } | |
| /*********************************************************************** | |
| * CreateDialog (USER.89) | |
| */ | |
| HWND CreateDialog( HINSTANCE hInst, LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc ) | |
| { | |
| return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 ); | |
| } | |
| /*********************************************************************** | |
| * CreateDialogParam (USER.241) | |
| */ | |
| HWND CreateDialogParam( HINSTANCE hInst, LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc, LPARAM param ) | |
| { | |
| HWND hwnd = 0; | |
| HANDLE hres, hmem; | |
| LPCSTR data; | |
| dprintf_dialog(stddeb, "CreateDialogParam: %d,'%p',%d,%p,%ld\n", | |
| hInst, dlgTemplate, owner, dlgProc, param ); | |
| /* FIXME: MAKEINTRESOURCE should be replaced by RT_DIALOG */ | |
| if (!(hres = FindResource( hInst, dlgTemplate, MAKEINTRESOURCE(0x8005) ))) | |
| return 0; | |
| if (!(hmem = LoadResource( hInst, hres ))) return 0; | |
| if (!(data = LockResource( hmem ))) hwnd = 0; | |
| else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param); | |
| FreeResource( hmem ); | |
| return hwnd; | |
| } | |
| /*********************************************************************** | |
| * CreateDialogIndirect (USER.219) | |
| */ | |
| HWND CreateDialogIndirect( HINSTANCE hInst, LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc ) | |
| { | |
| return CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 ); | |
| } | |
| /*********************************************************************** | |
| * CreateDialogIndirectParam (USER.242) | |
| */ | |
| HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc, LPARAM param ) | |
| { | |
| HMENU hMenu; | |
| HFONT hFont = 0; | |
| HWND hwnd, hwndCtrl; | |
| RECT rect; | |
| WND * wndPtr; | |
| int i; | |
| DLGTEMPLATE template; | |
| DLGCONTROLHEADER * header; | |
| DIALOGINFO * dlgInfo; | |
| DWORD exStyle = 0; | |
| WORD xUnit = xBaseUnit; | |
| WORD yUnit = yBaseUnit; | |
| /* Parse dialog template */ | |
| if (!dlgTemplate) return 0; | |
| header = DIALOG_ParseTemplate( dlgTemplate, &template ); | |
| if(debugging_dialog)DIALOG_DisplayTemplate( &template ); | |
| /* Load menu */ | |
| switch (template.menuName[0]) | |
| { | |
| case 0x00: | |
| hMenu = 0; | |
| break; | |
| case 0xff: | |
| hMenu = LoadMenu( hInst, MAKEINTRESOURCE( template.menuName[1] + | |
| 256*template.menuName[2] )); | |
| break; | |
| default: | |
| hMenu = LoadMenu( hInst, template.menuName ); | |
| break; | |
| } | |
| /* 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, 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; | |
| if (!(template.header->style & DS_ABSALIGN)) | |
| ClientToScreen( owner, (POINT *)&rect ); | |
| rect.right = rect.left + template.header->cx * xUnit / 4; | |
| rect.bottom = rect.top + template.header->cy * yUnit / 8; | |
| if (template.header->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME; | |
| AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle ); | |
| hwnd = CreateWindowEx( exStyle, template.className, template.caption, | |
| template.header->style, | |
| rect.left + template.header->x * xUnit / 4, | |
| rect.top + template.header->y * yUnit / 8, | |
| rect.right - rect.left, rect.bottom - rect.top, | |
| owner, hMenu, hInst, | |
| NULL ); | |
| if (!hwnd) | |
| { | |
| if (hFont) DeleteObject( hFont ); | |
| if (hMenu) DestroyMenu( hMenu ); | |
| return 0; | |
| } | |
| /* Create control windows */ | |
| dprintf_dialog(stddeb, " BEGIN\n" ); | |
| wndPtr = WIN_FindWndPtr( hwnd ); | |
| 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 * next_header; | |
| LPSTR class, text; | |
| HWND hwndDefButton = 0; | |
| next_header = DIALOG_GetControl( header, &class, &text ); | |
| dprintf_dialog(stddeb, " %s ", class); | |
| if ((int)text & 0xffff0000) | |
| dprintf_dialog(stddeb,"'%s'", text); | |
| else | |
| dprintf_dialog(stddeb,"%4X", (int)text & 0xffff); | |
| dprintf_dialog(stddeb," %d, %d, %d, %d, %d, %08lx\n", | |
| header->id, header->x, header->y, | |
| header->cx, header->cy, header->style ); | |
| if ((strcmp(class, "EDIT") == 0) && | |
| ((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; | |
| } | |
| HEAP_LocalInit(dlgInfo->hDialogHeap, GlobalLock(dlgInfo->hDialogHeap), 0x10000); | |
| } | |
| header->style |= WS_CHILD; | |
| hwndCtrl = CreateWindowEx( WS_EX_NOPARENTNOTIFY, | |
| class, text, header->style, | |
| header->x * xUnit / 4, header->y * yUnit / 8, | |
| header->cx * xUnit / 4, header->cy * yUnit / 8, | |
| hwnd, header->id, dlgInfo->hDialogHeap, NULL ); | |
| } | |
| else | |
| { | |
| header->style |= WS_CHILD; | |
| hwndCtrl = CreateWindowEx( WS_EX_NOPARENTNOTIFY, | |
| class, text, header->style, | |
| header->x * xUnit / 4, header->y * yUnit / 8, | |
| header->cx * xUnit / 4, header->cy * yUnit / 8, | |
| hwnd, header->id, hInst, NULL ); | |
| } | |
| /* 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, 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 = header->id; | |
| } | |
| header = next_header; | |
| } | |
| 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, dlgInfo->hUserFont, 0 ); | |
| if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param )) | |
| SetFocus( dlgInfo->hwndFocus ); | |
| return hwnd; | |
| } | |
| /*********************************************************************** | |
| * DIALOG_DoDialogBox | |
| */ | |
| static int DIALOG_DoDialogBox( HWND hwnd, HWND owner ) | |
| { | |
| WND * wndPtr; | |
| DIALOGINFO * dlgInfo; | |
| HANDLE msgHandle; | |
| MSG* lpmsg; | |
| int retval; | |
| /* Owner must be a top-level window */ | |
| while (owner && GetParent(owner)) owner = GetParent(owner); | |
| if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1; | |
| if (!(msgHandle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(MSG)))) return -1; | |
| lpmsg = (MSG *) USER_HEAP_ADDR( msgHandle ); | |
| dlgInfo = (DIALOGINFO *)wndPtr->wExtra; | |
| EnableWindow( owner, FALSE ); | |
| ShowWindow( hwnd, SW_SHOW ); | |
| while (MSG_InternalGetMessage( lpmsg, 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, LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc ) | |
| { | |
| return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 ); | |
| } | |
| /*********************************************************************** | |
| * DialogBoxParam (USER.239) | |
| */ | |
| int DialogBoxParam( HINSTANCE hInst, LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc, LPARAM param ) | |
| { | |
| HWND hwnd; | |
| dprintf_dialog(stddeb, "DialogBoxParam: %d,'%p',%d,%p,%ld\n", | |
| hInst, dlgTemplate, owner, 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, WNDPROC dlgProc ) | |
| { | |
| return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 ); | |
| } | |
| /*********************************************************************** | |
| * DialogBoxIndirectParam (USER.240) | |
| */ | |
| int DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate, | |
| HWND owner, WNDPROC dlgProc, LPARAM param ) | |
| { | |
| HWND hwnd; | |
| LPCSTR ptr; | |
| if (!(ptr = GlobalLock( dlgTemplate ))) return -1; | |
| hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param ); | |
| GlobalUnlock( dlgTemplate ); | |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); | |
| return -1; | |
| } | |
| /*********************************************************************** | |
| * DialogBoxIndirectParamPtr | |
| * like DialogBoxIndirectParam, but expects pointer to template | |
| */ | |
| int DialogBoxIndirectParamPtr(HINSTANCE hInst,LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc, LPARAM param) | |
| { | |
| HWND hwnd; | |
| hwnd = CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, param ); | |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); | |
| return -1; | |
| } | |
| /*********************************************************************** | |
| * DialogBoxIndirectPtr | |
| * like DialogBoxIndirect, but expects pointer to template | |
| */ | |
| int DialogBoxIndirectPtr( HINSTANCE hInst, LPCSTR dlgTemplate, | |
| HWND owner, WNDPROC dlgProc) | |
| { | |
| return DialogBoxIndirectParamPtr(hInst, dlgTemplate, owner, dlgProc, 0); | |
| } | |
| /*********************************************************************** | |
| * EndDialog (USER.88) | |
| */ | |
| void EndDialog( HWND hwnd, short retval ) | |
| { | |
| WND * wndPtr = WIN_FindWndPtr( hwnd ); | |
| DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra; | |
| dlgInfo->msgResult = retval; | |
| dlgInfo->fEnd = TRUE; | |
| dprintf_dialog(stddeb, "EndDialog: %d %d\n", hwnd, retval ); | |
| } | |
| /*********************************************************************** | |
| * 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: | |
| SendMessage( hwndDlg, WM_COMMAND, IDCANCEL, | |
| MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 )); | |
| break; | |
| case VK_RETURN: | |
| { | |
| DWORD dw = SendMessage( hwndDlg, DM_GETDEFID, 0, 0 ); | |
| if (HIWORD(dw) == DC_HASDEFID) | |
| SendMessage( hwndDlg, WM_COMMAND, LOWORD(dw), | |
| MAKELPARAM( GetDlgItem( hwndDlg, LOWORD(dw) ), | |
| BN_CLICKED )); | |
| else | |
| SendMessage( hwndDlg, WM_COMMAND, IDOK, | |
| MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 )); | |
| } | |
| break; | |
| } | |
| 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 ) | |
| { | |
| HWND curChild; | |
| WND * childPtr; | |
| WND * wndPtr; | |
| if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return 0; | |
| curChild = wndPtr->hwndChild; | |
| while(curChild) | |
| { | |
| childPtr = WIN_FindWndPtr( curChild ); | |
| if (childPtr->wIDmenu == id) return curChild; | |
| curChild = childPtr->hwndNext; | |
| } | |
| return 0; | |
| } | |
| /******************************************************************* | |
| * SendDlgItemMessage (USER.101) | |
| */ | |
| LONG SendDlgItemMessage(HWND hwnd, WORD id, UINT msg, WORD wParam, LONG 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, LPSTR lpString ) | |
| { | |
| SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString ); | |
| } | |
| /*********************************************************************** | |
| * GetDlgItemText (USER.93) | |
| */ | |
| int GetDlgItemText( HWND hwnd, WORD id, LPSTR 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 ) | |
| { | |
| HANDLE hText = USER_HEAP_ALLOC(0, 10 ); | |
| char * str = (char *) USER_HEAP_ADDR( hText ); | |
| if (fSigned) sprintf( str, "%d", value ); | |
| else sprintf( str, "%u", value ); | |
| SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)str ); | |
| USER_HEAP_FREE( hText ); | |
| } | |
| /*********************************************************************** | |
| * GetDlgItemInt (USER.95) | |
| */ | |
| WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned ) | |
| { | |
| int len; | |
| HANDLE hText; | |
| long result = 0; | |
| char * str; | |
| if (translated) *translated = FALSE; | |
| if (!(len = SendDlgItemMessage( hwnd, id, WM_GETTEXTLENGTH, 0, 0 ))) | |
| return 0; | |
| if (!(hText = USER_HEAP_ALLOC(0, len+1 ))) | |
| return 0; | |
| str = (char *) USER_HEAP_ADDR( hText ); | |
| if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, len+1, (DWORD)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; | |
| } | |
| } | |
| } | |
| USER_HEAP_FREE( hText ); | |
| return (WORD)result; | |
| } | |
| /*********************************************************************** | |
| * CheckDlgButton (USER.97) | |
| */ | |
| void CheckDlgButton( HWND hwnd, WORD id, WORD check ) | |
| { | |
| SendDlgItemMessage( hwnd, id, BM_SETCHECK, check, 0 ); | |
| } | |
| /*********************************************************************** | |
| * IsDlgButtonChecked (USER.98) | |
| */ | |
| WORD IsDlgButtonChecked( HWND hwnd, WORD id ) | |
| { | |
| return (WORD)SendDlgItemMessage( hwnd, id, BM_GETCHECK, 0, 0 ); | |
| } | |
| /*********************************************************************** | |
| * CheckRadioButton (USER.96) | |
| */ | |
| void CheckRadioButton( HWND hwndDlg, WORD firstID, WORD lastID, WORD checkID ) | |
| { | |
| HWND button = GetWindow( hwndDlg, GW_CHILD ); | |
| WND *wndPtr; | |
| while (button) | |
| { | |
| if (!(wndPtr = WIN_FindWndPtr( button ))) return; | |
| if ((wndPtr->wIDmenu == firstID) || (wndPtr->wIDmenu == lastID)) break; | |
| button = wndPtr->hwndNext; | |
| } | |
| if (!button) return; | |
| if (wndPtr->wIDmenu == lastID) | |
| lastID = firstID; /* Buttons are in reverse order */ | |
| while (button) | |
| { | |
| if (!(wndPtr = WIN_FindWndPtr( button ))) return; | |
| SendMessage( button, BM_SETCHECK, (wndPtr->wIDmenu == checkID), 0 ); | |
| if (wndPtr->wIDmenu == lastID) break; | |
| button = wndPtr->hwndNext; | |
| } | |
| } | |
| /*********************************************************************** | |
| * 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 ) | |
| { | |
| HWND hwnd, hwndStart; | |
| WND * dlgPtr, * ctrlPtr, * wndPtr; | |
| if (!(dlgPtr = WIN_FindWndPtr( hwndDlg ))) return 0; | |
| if (!(ctrlPtr = WIN_FindWndPtr( hwndCtrl ))) return 0; | |
| if (ctrlPtr->hwndParent != hwndDlg) return 0; | |
| if (!fPrevious && ctrlPtr->hwndNext) /*Check if next control is in group*/ | |
| { | |
| wndPtr = WIN_FindWndPtr( ctrlPtr->hwndNext ); | |
| if (!(wndPtr->dwStyle & WS_GROUP)) return ctrlPtr->hwndNext; | |
| } | |
| if (ctrlPtr->dwStyle & WS_GROUP) /* Control is the first of the group */ | |
| { | |
| if (!fPrevious) return hwndCtrl; /* Control is alone in his group */ | |
| hwnd = ctrlPtr->hwndNext; | |
| while(hwnd) /* Find last control of the group */ | |
| { | |
| wndPtr = WIN_FindWndPtr( hwnd ); | |
| if (wndPtr->dwStyle & WS_GROUP) break; | |
| hwndCtrl = hwnd; | |
| hwnd = wndPtr->hwndNext; | |
| } | |
| return hwndCtrl; | |
| } | |
| /* Now we will have to find the start of the group */ | |
| hwndStart = hwnd = dlgPtr->hwndChild; | |
| while (hwnd) | |
| { | |
| wndPtr = WIN_FindWndPtr( hwnd ); | |
| if (wndPtr->dwStyle & WS_GROUP) hwndStart = hwnd; /*Start of a group*/ | |
| if (hwnd == hwndCtrl) | |
| { | |
| /* We found the control -> hwndStart is the first of the group */ | |
| if (!fPrevious) return hwndStart; | |
| while(hwndStart) /* Find the control placed before hwndCtrl */ | |
| { | |
| wndPtr = WIN_FindWndPtr( hwndStart ); | |
| if (wndPtr->hwndNext == hwndCtrl) return hwndStart; | |
| hwndStart = wndPtr->hwndNext; | |
| } | |
| break; | |
| } | |
| hwnd = wndPtr->hwndNext; | |
| } | |
| return hwndCtrl; /* Not found -> return original control */ | |
| } | |
| /*********************************************************************** | |
| * GetNextDlgTabItem (USER.228) | |
| */ | |
| HWND GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious ) | |
| { | |
| HWND hwnd, hwndLast; | |
| WND * dlgPtr, * ctrlPtr, * wndPtr; | |
| if (!(dlgPtr = WIN_FindWndPtr( hwndDlg ))) return 0; | |
| if (!(ctrlPtr = WIN_FindWndPtr( hwndCtrl ))) return 0; | |
| if (ctrlPtr->hwndParent != hwndDlg) return 0; | |
| hwndLast = hwndCtrl; | |
| hwnd = ctrlPtr->hwndNext; | |
| while (1) | |
| { | |
| if (!hwnd) hwnd = dlgPtr->hwndChild; | |
| if (hwnd == hwndCtrl) break; | |
| wndPtr = WIN_FindWndPtr( hwnd ); | |
| if (wndPtr->dwStyle & WS_TABSTOP) | |
| { | |
| hwndLast = hwnd; | |
| if (!fPrevious) break; | |
| } | |
| hwnd = wndPtr->hwndNext; | |
| } | |
| return hwndLast; | |
| } |