| /* |
| * Dialog functions |
| * |
| * Copyright 1993, 1994, 1996 Alexandre Julliard |
| */ |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include "windows.h" |
| #include "dialog.h" |
| #include "heap.h" |
| #include "win.h" |
| #include "ldt.h" |
| #include "string32.h" |
| #include "user.h" |
| #include "winproc.h" |
| #include "message.h" |
| #include "stddebug.h" |
| #include "debug.h" |
| |
| |
| /* Dialog control information */ |
| typedef struct |
| { |
| DWORD style; |
| DWORD exStyle; |
| INT16 x; |
| INT16 y; |
| INT16 cx; |
| INT16 cy; |
| UINT16 id; |
| LPCSTR className; |
| LPCSTR windowName; |
| LPVOID data; |
| } DLG_CONTROL_INFO; |
| |
| /* Dialog template */ |
| typedef struct |
| { |
| DWORD style; |
| DWORD exStyle; |
| UINT16 nbItems; |
| INT16 x; |
| INT16 y; |
| INT16 cx; |
| INT16 cy; |
| LPCSTR menuName; |
| LPCSTR className; |
| LPCSTR caption; |
| WORD pointSize; |
| LPCSTR faceName; |
| } DLG_TEMPLATE; |
| |
| /* Dialog base units */ |
| static WORD xBaseUnit = 0, yBaseUnit = 0; |
| |
| |
| /*********************************************************************** |
| * DIALOG_Init |
| * |
| * Initialisation of the dialog manager. |
| */ |
| BOOL32 DIALOG_Init() |
| { |
| TEXTMETRIC16 tm; |
| HDC hdc; |
| |
| /* Calculate the dialog base units */ |
| |
| if (!(hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ))) return FALSE; |
| GetTextMetrics16( hdc, &tm ); |
| DeleteDC( 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_GetControl16 |
| * |
| * Return the class and text of the control pointed to by ptr, |
| * fill the header structure and return a pointer to the next control. |
| */ |
| static LPCSTR DIALOG_GetControl16( LPCSTR p, DLG_CONTROL_INFO *info ) |
| { |
| static char buffer[10]; |
| |
| info->x = GET_WORD(p); p += sizeof(WORD); |
| info->y = GET_WORD(p); p += sizeof(WORD); |
| info->cx = GET_WORD(p); p += sizeof(WORD); |
| info->cy = GET_WORD(p); p += sizeof(WORD); |
| info->id = GET_WORD(p); p += sizeof(WORD); |
| info->style = GET_DWORD(p); p += sizeof(DWORD); |
| info->exStyle = 0; |
| |
| if (*p & 0x80) |
| { |
| switch((BYTE)*p) |
| { |
| 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; |
| } |
| info->className = buffer; |
| p++; |
| } |
| else |
| { |
| info->className = p; |
| p += strlen(p) + 1; |
| } |
| dprintf_dialog(stddeb, " %s ", info->className ); |
| |
| if ((BYTE)*p == 0xff) |
| { |
| /* Integer id, not documented (?). Only works for SS_ICON controls */ |
| info->windowName = (LPCSTR)(UINT32)GET_WORD(p+1); |
| p += 3; |
| dprintf_dialog( stddeb,"%04x", LOWORD(info->windowName) ); |
| } |
| else |
| { |
| info->windowName = p; |
| p += strlen(p) + 1; |
| dprintf_dialog(stddeb,"'%s'", info->windowName ); |
| } |
| |
| info->data = (LPVOID)(*p ? p + 1 : NULL); /* FIXME: should be a segptr */ |
| p += *p + 1; |
| |
| dprintf_dialog( stddeb," %d, %d, %d, %d, %d, %08lx, %08lx\n", |
| info->id, info->x, info->y, info->cx, info->cy, |
| info->style, (DWORD)info->data); |
| return p; |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_GetControl32 |
| * |
| * Return the class and text of the control pointed to by ptr, |
| * fill the header structure and return a pointer to the next control. |
| */ |
| static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info ) |
| { |
| static WCHAR buffer[10]; |
| |
| info->style = GET_DWORD(p); p += 2; |
| info->exStyle = GET_DWORD(p); p += 2; |
| info->x = GET_WORD(p); p++; |
| info->y = GET_WORD(p); p++; |
| info->cx = GET_WORD(p); p++; |
| info->cy = GET_WORD(p); p++; |
| info->id = GET_WORD(p); p++; |
| |
| if (GET_WORD(p) == 0xffff) |
| { |
| switch(GET_WORD(p+1)) |
| { |
| case 0x80: STRING32_AnsiToUni( buffer, "BUTTON" ); break; |
| case 0x81: STRING32_AnsiToUni( buffer, "EDIT" ); break; |
| case 0x82: STRING32_AnsiToUni( buffer, "STATIC" ); break; |
| case 0x83: STRING32_AnsiToUni( buffer, "LISTBOX" ); break; |
| case 0x84: STRING32_AnsiToUni( buffer, "SCROLLBAR" ); break; |
| case 0x85: STRING32_AnsiToUni( buffer, "COMBOBOX" ); break; |
| default: buffer[0] = '\0'; break; |
| } |
| info->className = (LPCSTR)buffer; |
| p += 2; |
| } |
| else |
| { |
| info->className = (LPCSTR)p; |
| p += lstrlen32W( (LPCWSTR)p ) + 1; |
| } |
| dprintf_dialog(stddeb, " %p ", info->className ); |
| |
| if (GET_WORD(p) == 0xffff) |
| { |
| info->windowName = (LPCSTR)(p + 1); |
| p += 2; |
| dprintf_dialog( stddeb,"%04x", LOWORD(info->windowName) ); |
| } |
| else |
| { |
| info->windowName = (LPCSTR)p; |
| p += lstrlen32W( (LPCWSTR)p ) + 1; |
| dprintf_dialog(stddeb,"'%p'", info->windowName ); |
| } |
| |
| if (GET_WORD(p)) |
| { |
| info->data = (LPVOID)(p + 1); |
| p += GET_WORD(p) / sizeof(WORD); |
| } |
| else info->data = NULL; |
| p++; |
| |
| dprintf_dialog( stddeb," %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", |
| info->id, info->x, info->y, info->cx, info->cy, |
| info->style, info->exStyle, (DWORD)info->data); |
| /* Next control is on dword boundary */ |
| return (const WORD *)((((int)p) + 3) & ~3); |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_CreateControls |
| * |
| * Create the control windows for a dialog. |
| */ |
| static BOOL32 DIALOG_CreateControls( WND *pWnd, LPCSTR template, INT32 items, |
| HINSTANCE32 hInst, BOOL win32 ) |
| { |
| DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra; |
| DLG_CONTROL_INFO info; |
| HWND32 hwndCtrl, hwndDefButton = 0; |
| |
| dprintf_dialog(stddeb, " BEGIN\n" ); |
| while (items--) |
| { |
| if (!win32) |
| { |
| HINSTANCE16 instance; |
| template = DIALOG_GetControl16( template, &info ); |
| if (HIWORD(info.className) && !strcmp( info.className, "EDIT") && |
| ((info.style & DS_LOCALEDIT) != DS_LOCALEDIT)) |
| { |
| if (!dlgInfo->hDialogHeap) |
| { |
| dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000); |
| if (!dlgInfo->hDialogHeap) |
| { |
| fprintf( stderr, "CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n" ); |
| continue; |
| } |
| LocalInit(dlgInfo->hDialogHeap, 0, 0xffff); |
| } |
| instance = dlgInfo->hDialogHeap; |
| } |
| else instance = (HINSTANCE16)hInst; |
| |
| hwndCtrl = CreateWindowEx16( info.exStyle | WS_EX_NOPARENTNOTIFY, |
| info.className, info.windowName, |
| info.style | WS_CHILD, |
| info.x * dlgInfo->xBaseUnit / 4, |
| info.y * dlgInfo->yBaseUnit / 8, |
| info.cx * dlgInfo->xBaseUnit / 4, |
| info.cy * dlgInfo->yBaseUnit / 8, |
| pWnd->hwndSelf, (HMENU16)info.id, |
| instance, info.data ); |
| } |
| else |
| { |
| template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info ); |
| hwndCtrl = CreateWindowEx32W( info.exStyle | WS_EX_NOPARENTNOTIFY, |
| (LPCWSTR)info.className, |
| (LPCWSTR)info.windowName, |
| info.style | WS_CHILD, |
| info.x * dlgInfo->xBaseUnit / 4, |
| info.y * dlgInfo->yBaseUnit / 8, |
| info.cx * dlgInfo->xBaseUnit / 4, |
| info.cy * dlgInfo->yBaseUnit / 8, |
| pWnd->hwndSelf, (HMENU32)info.id, |
| hInst, info.data ); |
| } |
| if (!hwndCtrl) return FALSE; |
| |
| /* Send initialisation messages to the control */ |
| if (dlgInfo->hUserFont) SendMessage32A( hwndCtrl, WM_SETFONT, |
| (WPARAM)dlgInfo->hUserFont, 0 ); |
| if (SendMessage32A(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) |
| SendMessage32A( hwndDefButton, BM_SETSTYLE32, |
| BS_PUSHBUTTON,FALSE ); |
| hwndDefButton = hwndCtrl; |
| dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID ); |
| } |
| } |
| dprintf_dialog(stddeb, " END\n" ); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_ParseTemplate16 |
| * |
| * Fill a DLG_TEMPLATE structure from the dialog template, and return |
| * a pointer to the first control. |
| */ |
| static LPCSTR DIALOG_ParseTemplate16( LPCSTR p, DLG_TEMPLATE * result ) |
| { |
| result->style = GET_DWORD(p); p += sizeof(DWORD); |
| result->exStyle = 0; |
| result->nbItems = *p++; |
| result->x = GET_WORD(p); p += sizeof(WORD); |
| result->y = GET_WORD(p); p += sizeof(WORD); |
| result->cx = GET_WORD(p); p += sizeof(WORD); |
| result->cy = GET_WORD(p); p += sizeof(WORD); |
| dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n", |
| result->x, result->y, result->cx, result->cy ); |
| dprintf_dialog( stddeb, " STYLE %08lx\n", result->style ); |
| |
| /* Get the menu name */ |
| |
| switch( (BYTE)*p ) |
| { |
| case 0: |
| result->menuName = 0; |
| p++; |
| break; |
| case 0xff: |
| result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 ); |
| p += 3; |
| dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) ); |
| break; |
| default: |
| result->menuName = p; |
| dprintf_dialog( stddeb, " MENU '%s'\n", p ); |
| p += strlen(p) + 1; |
| break; |
| } |
| |
| /* Get the class name */ |
| |
| if (*p) |
| { |
| result->className = p; |
| dprintf_dialog( stddeb, " CLASS '%s'\n", result->className ); |
| } |
| else result->className = DIALOG_CLASS_ATOM; |
| p += strlen(p) + 1; |
| |
| /* Get the window caption */ |
| |
| result->caption = p; |
| p += strlen(p) + 1; |
| dprintf_dialog( stddeb, " CAPTION '%s'\n", result->caption ); |
| |
| /* Get the font name */ |
| |
| if (result->style & DS_SETFONT) |
| { |
| result->pointSize = GET_WORD(p); |
| p += sizeof(WORD); |
| result->faceName = p; |
| p += strlen(p) + 1; |
| dprintf_dialog( stddeb, " FONT %d,'%s'\n", |
| result->pointSize, result->faceName ); |
| } |
| return p; |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_ParseTemplate32 |
| * |
| * Fill a DLG_TEMPLATE structure from the dialog template, and return |
| * a pointer to the first control. |
| */ |
| static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result ) |
| { |
| const WORD *p = (const WORD *)template; |
| |
| result->style = GET_DWORD(p); p += 2; |
| result->exStyle = GET_DWORD(p); p += 2; |
| result->nbItems = GET_WORD(p); p++; |
| result->x = GET_WORD(p); p++; |
| result->y = GET_WORD(p); p++; |
| result->cx = GET_WORD(p); p++; |
| result->cy = GET_WORD(p); p++; |
| dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n", |
| result->x, result->y, result->cx, result->cy ); |
| dprintf_dialog( stddeb, " STYLE %08lx\n", result->style ); |
| dprintf_dialog( stddeb, " EXSTYLE %08lx\n", result->exStyle ); |
| |
| /* Get the menu name */ |
| |
| switch(GET_WORD(p)) |
| { |
| case 0x0000: |
| result->menuName = NULL; |
| p++; |
| break; |
| case 0xffff: |
| result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 ); |
| p += 2; |
| dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) ); |
| break; |
| default: |
| result->menuName = (LPCSTR)p; |
| dprintf_dialog( stddeb, " MENU '%p'\n", p ); |
| p += lstrlen32W( (LPCWSTR)p ) + 1; |
| break; |
| } |
| |
| /* Get the class name */ |
| |
| switch(GET_WORD(p)) |
| { |
| case 0x0000: |
| result->className = DIALOG_CLASS_ATOM; |
| p++; |
| break; |
| case 0xffff: |
| result->className = (LPCSTR)(UINT32)GET_WORD( p + 1 ); |
| p += 2; |
| dprintf_dialog(stddeb, " CLASS %04x\n", LOWORD(result->className) ); |
| break; |
| default: |
| result->className = (LPCSTR)p; |
| dprintf_dialog( stddeb, " CLASS '%p'\n", p ); |
| p += lstrlen32W( (LPCWSTR)p ) + 1; |
| break; |
| } |
| |
| /* Get the window caption */ |
| |
| result->caption = (LPCSTR)p; |
| p += lstrlen32W( (LPCWSTR)p ) + 1; |
| dprintf_dialog( stddeb, " CAPTION '%p'\n", result->caption ); |
| |
| /* Get the font name */ |
| |
| if (result->style & DS_SETFONT) |
| { |
| result->pointSize = GET_WORD(p); |
| p++; |
| result->faceName = (LPCSTR)p; |
| p += lstrlen32W( (LPCWSTR)p ) + 1; |
| dprintf_dialog( stddeb, " FONT %d,'%p'\n", |
| result->pointSize, result->faceName ); |
| } |
| /* First control is on dword boundary */ |
| return (LPCSTR)((((int)p) + 3) & ~3); |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_CreateIndirect |
| */ |
| static HWND DIALOG_CreateIndirect( HINSTANCE32 hInst, LPCSTR dlgTemplate, |
| HWND owner, DLGPROC16 dlgProc, |
| LPARAM param, WINDOWPROCTYPE procType ) |
| { |
| HMENU16 hMenu = 0; |
| HFONT16 hFont = 0; |
| HWND hwnd; |
| RECT16 rect; |
| WND * wndPtr; |
| DLG_TEMPLATE template; |
| DIALOGINFO * dlgInfo; |
| WORD xUnit = xBaseUnit; |
| WORD yUnit = yBaseUnit; |
| |
| /* Parse dialog template */ |
| |
| if (!dlgTemplate) return 0; |
| if (procType != WIN_PROC_16) |
| dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template ); |
| else |
| dlgTemplate = DIALOG_ParseTemplate16( dlgTemplate, &template ); |
| |
| /* Load menu */ |
| |
| if (template.menuName) |
| { |
| LPSTR str = SEGPTR_STRDUP( template.menuName ); /* FIXME: win32 */ |
| hMenu = LoadMenu16( hInst, SEGPTR_GET(str) ); |
| SEGPTR_FREE( str ); |
| } |
| |
| /* Create custom font if needed */ |
| |
| if (template.style & DS_SETFONT) |
| { |
| /* The font height must be negative as it is a point size */ |
| /* (see CreateFont() documentation in the Windows SDK). */ |
| hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE, |
| FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, |
| DEFAULT_QUALITY, FF_DONTCARE, |
| template.faceName ); /* FIXME: win32 */ |
| if (hFont) |
| { |
| TEXTMETRIC16 tm; |
| HFONT16 oldFont; |
| |
| HDC32 hdc = GetDC32(0); |
| oldFont = SelectObject( hdc, hFont ); |
| GetTextMetrics16( hdc, &tm ); |
| SelectObject( hdc, oldFont ); |
| ReleaseDC32( 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.cx * xUnit / 4; |
| rect.bottom = template.cy * yUnit / 8; |
| if (template.style & DS_MODALFRAME) |
| template.exStyle |= WS_EX_DLGMODALFRAME; |
| AdjustWindowRectEx16( &rect, template.style, |
| hMenu ? TRUE : FALSE , template.exStyle ); |
| rect.right -= rect.left; |
| rect.bottom -= rect.top; |
| |
| if ((INT16)template.x == CW_USEDEFAULT16) |
| { |
| rect.left = rect.top = (procType == WIN_PROC_16) ? CW_USEDEFAULT16 |
| : CW_USEDEFAULT32; |
| } |
| else |
| { |
| rect.left += template.x * xUnit / 4; |
| rect.top += template.y * yUnit / 8; |
| if ( !(template.style & DS_ABSALIGN) && !(template.style & WS_CHILD) ) |
| ClientToScreen16( owner, (POINT16 *)&rect ); |
| } |
| |
| if (procType != WIN_PROC_16) |
| hwnd = CreateWindowEx32W(template.exStyle, (LPCWSTR)template.className, |
| (LPCWSTR)template.caption, |
| template.style & ~WS_VISIBLE, |
| rect.left, rect.top, rect.right, rect.bottom, |
| owner, hMenu, hInst, NULL ); |
| else |
| hwnd = CreateWindowEx16(template.exStyle, template.className, |
| template.caption, template.style & ~WS_VISIBLE, |
| rect.left, rect.top, rect.right, rect.bottom, |
| owner, hMenu, hInst, NULL ); |
| if (!hwnd) |
| { |
| if (hFont) DeleteObject( hFont ); |
| if (hMenu) DestroyMenu( hMenu ); |
| return 0; |
| } |
| wndPtr = WIN_FindWndPtr( hwnd ); |
| wndPtr->flags |= WIN_ISDIALOG; |
| |
| /* Initialise dialog extra data */ |
| |
| dlgInfo = (DIALOGINFO *)wndPtr->wExtra; |
| WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType ); |
| dlgInfo->hUserFont = hFont; |
| dlgInfo->hMenu = hMenu; |
| dlgInfo->xBaseUnit = xUnit; |
| dlgInfo->yBaseUnit = yUnit; |
| dlgInfo->msgResult = 0; /* This is used to store the default button id */ |
| dlgInfo->hDialogHeap = 0; |
| |
| /* Create controls */ |
| |
| if (!DIALOG_CreateControls( wndPtr, dlgTemplate, template.nbItems, |
| hInst, (procType != WIN_PROC_16) )) |
| { |
| DestroyWindow( hwnd ); |
| return 0; |
| } |
| |
| /* Send initialisation messages and set focus */ |
| |
| dlgInfo->hwndFocus = GetNextDlgTabItem32( hwnd, 0, FALSE ); |
| if (dlgInfo->hUserFont) |
| SendMessage32A( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 ); |
| if (SendMessage32A(hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param)) |
| SetFocus32( dlgInfo->hwndFocus ); |
| if (template.style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); |
| return hwnd; |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialog16 (USER.89) |
| */ |
| HWND16 CreateDialog16( HINSTANCE16 hInst, SEGPTR dlgTemplate, |
| HWND16 owner, DLGPROC16 dlgProc ) |
| { |
| return CreateDialogParam16( hInst, dlgTemplate, owner, dlgProc, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogParam16 (USER.241) |
| */ |
| HWND16 CreateDialogParam16( HINSTANCE16 hInst, SEGPTR dlgTemplate, |
| HWND16 owner, DLGPROC16 dlgProc, LPARAM param ) |
| { |
| HWND16 hwnd = 0; |
| HRSRC16 hRsrc; |
| HGLOBAL16 hmem; |
| LPCVOID data; |
| |
| dprintf_dialog(stddeb, "CreateDialogParam16: %04x,%08lx,%04x,%08lx,%ld\n", |
| hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param ); |
| |
| if (!(hRsrc = FindResource16( hInst, dlgTemplate, RT_DIALOG ))) return 0; |
| if (!(hmem = LoadResource16( hInst, hRsrc ))) return 0; |
| if (!(data = LockResource16( hmem ))) hwnd = 0; |
| else hwnd = CreateDialogIndirectParam16( hInst, data, owner, |
| dlgProc, param ); |
| FreeResource16( hmem ); |
| return hwnd; |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogParam32A (USER32.72) |
| */ |
| HWND32 CreateDialogParam32A( HINSTANCE32 hInst, LPCSTR name, |
| HWND32 owner, DLGPROC32 dlgProc, LPARAM param ) |
| { |
| if (HIWORD(name)) |
| { |
| LPWSTR str = STRING32_DupAnsiToUni( name ); |
| HWND32 hwnd = CreateDialogParam32W( hInst, str, owner, dlgProc, param); |
| free( str ); |
| return hwnd; |
| } |
| return CreateDialogParam32W( hInst, (LPCWSTR)name, owner, dlgProc, param ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogParam32W (USER32.73) |
| */ |
| HWND32 CreateDialogParam32W( HINSTANCE32 hInst, LPCWSTR name, |
| HWND32 owner, DLGPROC32 dlgProc, LPARAM param ) |
| { |
| HANDLE32 hrsrc = FindResource32W( hInst, name, (LPWSTR)RT_DIALOG ); |
| if (!hrsrc) return 0; |
| return CreateDialogIndirectParam32W( hInst, |
| (LPVOID)LoadResource32(hInst, hrsrc), |
| owner, dlgProc, param ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogIndirect16 (USER.219) |
| */ |
| HWND16 CreateDialogIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate, |
| HWND16 owner, DLGPROC16 dlgProc ) |
| { |
| return CreateDialogIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogIndirectParam16 (USER.242) |
| */ |
| HWND16 CreateDialogIndirectParam16( HINSTANCE16 hInst, LPCVOID dlgTemplate, |
| HWND16 owner, DLGPROC16 dlgProc, |
| LPARAM param ) |
| { |
| return DIALOG_CreateIndirect( hInst, dlgTemplate, owner, |
| dlgProc, param, WIN_PROC_16 ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogIndirectParam32A (USER32.69) |
| */ |
| HWND32 CreateDialogIndirectParam32A( HINSTANCE32 hInst, LPCVOID dlgTemplate, |
| HWND32 owner, DLGPROC32 dlgProc, |
| LPARAM param ) |
| { |
| return DIALOG_CreateIndirect( hInst, dlgTemplate, owner, |
| (DLGPROC16)dlgProc, param, WIN_PROC_32A ); |
| } |
| |
| |
| /*********************************************************************** |
| * CreateDialogIndirectParam32W (USER32.71) |
| */ |
| HWND32 CreateDialogIndirectParam32W( HINSTANCE32 hInst, LPCVOID dlgTemplate, |
| HWND32 owner, DLGPROC32 dlgProc, |
| LPARAM param ) |
| { |
| return DIALOG_CreateIndirect( hInst, dlgTemplate, owner, |
| (DLGPROC16)dlgProc, param, WIN_PROC_32W ); |
| } |
| |
| |
| /*********************************************************************** |
| * DIALOG_DoDialogBox |
| */ |
| static INT32 DIALOG_DoDialogBox( HWND hwnd, HWND owner ) |
| { |
| WND * wndPtr; |
| DIALOGINFO * dlgInfo; |
| MSG16 msg; |
| INT32 retval; |
| |
| /* Owner must be a top-level window */ |
| owner = WIN_GetTopParent( owner ); |
| if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1; |
| dlgInfo = (DIALOGINFO *)wndPtr->wExtra; |
| EnableWindow( owner, FALSE ); |
| ShowWindow( hwnd, SW_SHOW ); |
| |
| while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE, |
| !(wndPtr->dwStyle & DS_NOIDLEMSG) )) |
| { |
| if (!IsDialogMessage( hwnd, &msg)) |
| { |
| TranslateMessage( &msg ); |
| DispatchMessage( &msg ); |
| } |
| if (dlgInfo->fEnd) break; |
| } |
| retval = dlgInfo->msgResult; |
| EnableWindow( owner, TRUE ); |
| DestroyWindow( hwnd ); |
| return retval; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBox16 (USER.87) |
| */ |
| INT16 DialogBox16( HINSTANCE16 hInst, SEGPTR dlgTemplate, |
| HWND16 owner, DLGPROC16 dlgProc ) |
| { |
| return DialogBoxParam16( hInst, dlgTemplate, owner, dlgProc, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxParam16 (USER.239) |
| */ |
| INT16 DialogBoxParam16( HINSTANCE16 hInst, SEGPTR template, |
| HWND16 owner, DLGPROC16 dlgProc, LPARAM param ) |
| { |
| HWND16 hwnd = CreateDialogParam16( hInst, template, owner, dlgProc, param); |
| if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxParam32A (USER32.138) |
| */ |
| INT32 DialogBoxParam32A( HINSTANCE32 hInst, LPCSTR name, |
| HWND32 owner, DLGPROC32 dlgProc, LPARAM param ) |
| { |
| HWND32 hwnd = CreateDialogParam32A( hInst, name, owner, dlgProc, param ); |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxParam32W (USER32.139) |
| */ |
| INT32 DialogBoxParam32W( HINSTANCE32 hInst, LPCWSTR name, |
| HWND32 owner, DLGPROC32 dlgProc, LPARAM param ) |
| { |
| HWND32 hwnd = CreateDialogParam32W( hInst, name, owner, dlgProc, param ); |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxIndirect16 (USER.218) |
| */ |
| INT16 DialogBoxIndirect16( HINSTANCE16 hInst, HANDLE16 dlgTemplate, |
| HWND16 owner, DLGPROC16 dlgProc ) |
| { |
| return DialogBoxIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxIndirectParam16 (USER.240) |
| */ |
| INT16 DialogBoxIndirectParam16( HINSTANCE16 hInst, HANDLE16 dlgTemplate, |
| HWND16 owner, DLGPROC16 dlgProc, LPARAM param ) |
| { |
| HWND16 hwnd; |
| LPCVOID ptr; |
| |
| if (!(ptr = GlobalLock16( dlgTemplate ))) return -1; |
| hwnd = CreateDialogIndirectParam16( hInst, ptr, owner, dlgProc, param ); |
| GlobalUnlock16( dlgTemplate ); |
| if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxIndirectParam32A (USER32.135) |
| */ |
| INT32 DialogBoxIndirectParam32A( HINSTANCE32 hInstance, LPCVOID template, |
| HWND32 owner, DLGPROC32 dlgProc ,LPARAM param) |
| { |
| HWND32 hwnd = CreateDialogIndirectParam32A( hInstance, template, |
| owner, dlgProc, param ); |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * DialogBoxIndirectParam32W (USER32.137) |
| */ |
| INT32 DialogBoxIndirectParam32W( HINSTANCE32 hInstance, LPCVOID template, |
| HWND32 owner, DLGPROC32 dlgProc ,LPARAM param) |
| { |
| HWND32 hwnd = CreateDialogIndirectParam32W( hInstance, template, |
| owner, dlgProc, param ); |
| if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); |
| return -1; |
| } |
| |
| |
| /*********************************************************************** |
| * EndDialog (USER.88) (USER32.173) |
| */ |
| BOOL16 EndDialog( HWND32 hwnd, INT32 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, LPMSG16 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 = SendMessage16( 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)) |
| { |
| SendMessage16( hwndDlg, WM_NEXTDLGCTL, |
| (GetKeyState(VK_SHIFT) & 0x8000), 0 ); |
| return TRUE; |
| } |
| break; |
| |
| case VK_RIGHT: |
| case VK_DOWN: |
| if (!(dlgCode & DLGC_WANTARROWS)) |
| { |
| SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(), |
| FALSE ) ); |
| return TRUE; |
| } |
| break; |
| |
| case VK_LEFT: |
| case VK_UP: |
| if (!(dlgCode & DLGC_WANTARROWS)) |
| { |
| SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(), |
| TRUE ) ); |
| return TRUE; |
| } |
| break; |
| |
| case VK_ESCAPE: |
| SendMessage32A( hwndDlg, WM_COMMAND, IDCANCEL, |
| (LPARAM)GetDlgItem( hwndDlg, IDCANCEL ) ); |
| break; |
| |
| case VK_RETURN: |
| { |
| DWORD dw = SendMessage16( hwndDlg, DM_GETDEFID, 0, 0 ); |
| if (HIWORD(dw) == DC_HASDEFID) |
| SendMessage32A( hwndDlg, WM_COMMAND, |
| MAKEWPARAM( LOWORD(dw), BN_CLICKED ), |
| (LPARAM)GetDlgItem( hwndDlg, LOWORD(dw) )); |
| else |
| SendMessage32A( hwndDlg, WM_COMMAND, IDOK, |
| (LPARAM)GetDlgItem( hwndDlg, IDOK ) ); |
| } |
| 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) (USER32.233) |
| */ |
| INT16 GetDlgCtrlID( HWND32 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; |
| } |
| |
| |
| /******************************************************************* |
| * SendDlgItemMessage16 (USER.101) |
| */ |
| LRESULT SendDlgItemMessage16( HWND16 hwnd, INT16 id, UINT16 msg, |
| WPARAM16 wParam, LPARAM lParam ) |
| { |
| HWND16 hwndCtrl = GetDlgItem( hwnd, id ); |
| if (hwndCtrl) return SendMessage16( hwndCtrl, msg, wParam, lParam ); |
| else return 0; |
| } |
| |
| |
| /******************************************************************* |
| * SendDlgItemMessage32A (USER32.451) |
| */ |
| LRESULT SendDlgItemMessage32A( HWND32 hwnd, INT32 id, UINT32 msg, |
| WPARAM32 wParam, LPARAM lParam ) |
| { |
| HWND hwndCtrl = GetDlgItem( (HWND16)hwnd, (INT16)id ); |
| if (hwndCtrl) return SendMessage32A( hwndCtrl, msg, wParam, lParam ); |
| else return 0; |
| } |
| |
| |
| /******************************************************************* |
| * SendDlgItemMessage32W (USER32.452) |
| */ |
| LRESULT SendDlgItemMessage32W( HWND32 hwnd, INT32 id, UINT32 msg, |
| WPARAM32 wParam, LPARAM lParam ) |
| { |
| HWND hwndCtrl = GetDlgItem( (HWND16)hwnd, (INT16)id ); |
| if (hwndCtrl) return SendMessage32W( hwndCtrl, msg, wParam, lParam ); |
| else return 0; |
| } |
| |
| |
| /******************************************************************* |
| * SetDlgItemText16 (USER.92) |
| */ |
| void SetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR lpString ) |
| { |
| SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); |
| } |
| |
| |
| /******************************************************************* |
| * SetDlgItemText32A (USER32.477) |
| */ |
| void SetDlgItemText32A( HWND32 hwnd, INT32 id, LPCSTR lpString ) |
| { |
| SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); |
| } |
| |
| |
| /******************************************************************* |
| * SetDlgItemText32W (USER32.478) |
| */ |
| void SetDlgItemText32W( HWND32 hwnd, INT32 id, LPCWSTR lpString ) |
| { |
| SendDlgItemMessage32W( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetDlgItemText16 (USER.93) |
| */ |
| INT16 GetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR str, UINT16 len ) |
| { |
| return (INT16)SendDlgItemMessage16( hwnd, id, WM_GETTEXT, |
| len, (LPARAM)str ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetDlgItemText32A (USER32.236) |
| */ |
| INT32 GetDlgItemText32A( HWND32 hwnd, INT32 id, LPSTR str, UINT32 len ) |
| { |
| return (INT32)SendDlgItemMessage32A( hwnd, id, WM_GETTEXT, |
| len, (LPARAM)str ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetDlgItemText32W (USER32.237) |
| */ |
| INT32 GetDlgItemText32W( HWND32 hwnd, INT32 id, LPWSTR str, UINT32 len ) |
| { |
| return (INT32)SendDlgItemMessage32W( hwnd, id, WM_GETTEXT, |
| len, (LPARAM)str ); |
| } |
| |
| |
| /******************************************************************* |
| * SetDlgItemInt16 (USER.94) |
| */ |
| void SetDlgItemInt16( HWND16 hwnd, INT16 id, UINT16 value, BOOL16 fSigned ) |
| { |
| char *str = (char *)SEGPTR_ALLOC( 20 * sizeof(char) ); |
| |
| if (!str) return; |
| if (fSigned) sprintf( str, "%d", (INT32)(INT16)value ); |
| else sprintf( str, "%u", value ); |
| SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)SEGPTR_GET(str) ); |
| SEGPTR_FREE(str); |
| } |
| |
| |
| /******************************************************************* |
| * SetDlgItemInt32 (USER32.476) |
| */ |
| void SetDlgItemInt32( HWND32 hwnd, INT32 id, UINT32 value, BOOL32 fSigned ) |
| { |
| char str[20]; |
| |
| if (fSigned) sprintf( str, "%d", (INT32)value ); |
| else sprintf( str, "%u", value ); |
| SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)str ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetDlgItemInt (USER.95) |
| */ |
| WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned ) |
| { |
| char *str; |
| long result = 0; |
| |
| if (translated) *translated = FALSE; |
| if (!(str = (char *)SEGPTR_ALLOC( 30 * sizeof(char) ))) return 0; |
| if (SendDlgItemMessage16( hwnd, id, WM_GETTEXT, 30, (LPARAM)SEGPTR_GET(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; |
| } |
| } |
| } |
| SEGPTR_FREE(str); |
| return (WORD)result; |
| } |
| |
| |
| /*********************************************************************** |
| * CheckDlgButton (USER.97) (USER32.44) |
| */ |
| BOOL16 CheckDlgButton( HWND32 hwnd, INT32 id, UINT32 check ) |
| { |
| SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 ); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * IsDlgButtonChecked (USER.98) |
| */ |
| WORD IsDlgButtonChecked( HWND hwnd, WORD id ) |
| { |
| return (WORD)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 ); |
| } |
| |
| |
| /*********************************************************************** |
| * CheckRadioButton (USER.96) (USER32.47) |
| */ |
| BOOL16 CheckRadioButton( HWND32 hwndDlg, UINT32 firstID, UINT32 lastID, |
| UINT32 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) |
| { |
| SendMessage32A( pWnd->hwndSelf, BM_SETCHECK32, |
| (pWnd->wIDmenu == checkID), 0 ); |
| if (pWnd->wIDmenu == lastID) break; |
| pWnd = pWnd->next; |
| } |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * GetDialogBaseUnits (USER.243) |
| */ |
| DWORD GetDialogBaseUnits() |
| { |
| return MAKELONG( xBaseUnit, yBaseUnit ); |
| } |
| |
| |
| /*********************************************************************** |
| * MapDialogRect16 (USER.103) |
| */ |
| void MapDialogRect16( HWND16 hwnd, LPRECT16 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; |
| } |
| |
| |
| /*********************************************************************** |
| * MapDialogRect32 (USER32.381) |
| */ |
| void MapDialogRect32( HWND32 hwnd, LPRECT32 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; |
| } |
| |
| |
| /*********************************************************************** |
| * GetNextDlgGroupItem16 (USER.227) |
| */ |
| HWND16 GetNextDlgGroupItem16(HWND16 hwndDlg, HWND16 hwndCtrl, BOOL16 fPrevious) |
| { |
| return (HWND16)GetNextDlgGroupItem32( hwndDlg, hwndCtrl, fPrevious ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetNextDlgGroupItem32 (USER32.274) |
| */ |
| HWND32 GetNextDlgGroupItem32(HWND32 hwndDlg, HWND32 hwndCtrl, BOOL32 fPrevious) |
| { |
| WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg; |
| |
| if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; |
| if (hwndCtrl) |
| { |
| if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0; |
| /* Make sure hwndCtrl is a top-level child */ |
| while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg)) |
| pWndCtrl = pWndCtrl->parent; |
| if (pWndCtrl->parent != pWndDlg) return 0; |
| } |
| else |
| { |
| /* No ctrl specified -> start from the beginning */ |
| if (!(pWndCtrl = pWndDlg->child)) return 0; |
| if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next; |
| } |
| |
| pWndLast = pWndCtrl; |
| pWnd = pWndCtrl->next; |
| while (1) |
| { |
| if (!pWnd || (pWnd->dwStyle & WS_GROUP)) |
| { |
| /* Wrap-around to the beginning of the group */ |
| WND *pWndStart = pWndDlg->child; |
| for (pWnd = pWndStart; pWnd; pWnd = pWnd->next) |
| { |
| if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd; |
| if (pWnd == pWndCtrl) break; |
| } |
| pWnd = pWndStart; |
| } |
| if (pWnd == pWndCtrl) break; |
| if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED)) |
| { |
| pWndLast = pWnd; |
| if (!fPrevious) break; |
| } |
| pWnd = pWnd->next; |
| } |
| return pWndLast->hwndSelf; |
| } |
| |
| |
| /*********************************************************************** |
| * GetNextDlgTabItem16 (USER.228) |
| */ |
| HWND16 GetNextDlgTabItem16( HWND16 hwndDlg, HWND16 hwndCtrl, BOOL16 fPrevious ) |
| { |
| return (HWND16)GetNextDlgTabItem32( hwndDlg, hwndCtrl, fPrevious ); |
| } |
| |
| |
| /*********************************************************************** |
| * GetNextDlgTabItem32 (USER32.275) |
| */ |
| HWND32 GetNextDlgTabItem32( HWND32 hwndDlg, HWND32 hwndCtrl, BOOL32 fPrevious ) |
| { |
| WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg; |
| |
| if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; |
| if (hwndCtrl) |
| { |
| if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0; |
| /* Make sure hwndCtrl is a top-level child */ |
| while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg)) |
| pWndCtrl = pWndCtrl->parent; |
| if (pWndCtrl->parent != pWndDlg) return 0; |
| } |
| else |
| { |
| /* No ctrl specified -> start from the beginning */ |
| if (!(pWndCtrl = pWndDlg->child)) return 0; |
| if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next; |
| } |
| |
| 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) && |
| !(pWnd->dwStyle & WS_DISABLED)) |
| { |
| pWndLast = pWnd; |
| if (!fPrevious) break; |
| } |
| pWnd = pWnd->next; |
| } |
| return pWndLast->hwndSelf; |
| } |