windows-nt/Source/XPSP1/NT/windows/winstate/cobra/utils/main/wnd.c
2020-09-26 16:20:57 +08:00

537 lines
9.8 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
wnd.c
Abstract:
Utilities for window management
Author:
Jim Schmidt (jimschm) 01-Feb-2000
Revision History:
--*/
//
// Includes
//
#include "pch.h"
#define DBG_WND "Wnd"
//
// Strings
//
// None
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
typedef struct {
PCSTR WindowTitle;
DWORD ProcessId;
HWND Match;
} FINDWINDOW_STRUCTA, *PFINDWINDOW_STRUCTA;
typedef struct {
PCWSTR WindowTitle;
DWORD ProcessId;
HWND Match;
} FINDWINDOW_STRUCTW, *PFINDWINDOW_STRUCTW;
//
// Globals
//
static INT g_CursorRefCount = 0;
static HCURSOR g_OldCursor = NULL;
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
// None
//
// Code
//
BOOL
CALLBACK
pEnumWndProcA (
HWND hwnd,
LPARAM lParam
)
/*++
Routine Description:
A callback that is called for every top level window on the system. It is
used with pFindParentWindow to locate a specific window.
Arguments:
hwnd - Specifies the handle of the current enumerated window
lParam - Specifies a pointer to a FINDWINDOW_STRUCTA variable that
holds WindowTitle and ProcessId, and receives the
handle if a match is found.
Return Value:
The handle to the matching window, or NULL if no window has the
specified title and process ID.
--*/
{
CHAR title[MAX_MBCHAR_PATH];
DWORD processId;
PFINDWINDOW_STRUCTA p;
BOOL match = FALSE;
p = (PFINDWINDOW_STRUCTA) lParam;
if (!GetWindowThreadProcessId (hwnd, &processId)) {
DEBUGMSG ((DBG_WND, "Enumerated hwnd no longer valid"));
return TRUE;
}
if (processId == p->ProcessId) {
match = TRUE;
}
if (p->WindowTitle) {
GetWindowTextA (hwnd, title, ARRAYSIZE(title));
DEBUGMSGA ((
DBG_NAUSEA,
"Testing window: %s, ID=%08Xh against %s, %08Xh",
title,
processId,
p->WindowTitle,
p->ProcessId
));
match = match && StringMatchA (title, p->WindowTitle);
}
ELSE_DEBUGMSGA ((
DBG_NAUSEA,
"Testing window: Process ID=%08Xh against %08Xh",
processId,
p->ProcessId
));
if (match) {
p->Match = hwnd;
#ifdef DEBUG
//
// Get the window title for the following debug message
//
GetWindowTextA (hwnd, title, ARRAYSIZE(title));
DEBUGMSGA ((
DBG_NAUSEA,
"Window found: %s, ID=%u",
title,
processId
));
#endif
return FALSE; // stop enum
}
return TRUE; // continue enum
}
BOOL
CALLBACK
pEnumWndProcW (
HWND hwnd,
LPARAM lParam
)
{
WCHAR title[MAX_MBCHAR_PATH];
DWORD processId;
PFINDWINDOW_STRUCTW p;
BOOL match = FALSE;
p = (PFINDWINDOW_STRUCTW) lParam;
if (!GetWindowThreadProcessId (hwnd, &processId)) {
DEBUGMSG ((DBG_WND, "Enumerated hwnd no longer valid"));
return TRUE;
}
if (processId == p->ProcessId) {
match = TRUE;
}
if (p->WindowTitle) {
GetWindowTextW (hwnd, title, ARRAYSIZE(title));
DEBUGMSGW ((
DBG_NAUSEA,
"Testing window: %s, ID=%08Xh against %s, %08Xh",
title,
processId,
p->WindowTitle,
p->ProcessId
));
match = match && StringMatchW (title, p->WindowTitle);
}
ELSE_DEBUGMSGW ((
DBG_NAUSEA,
"Testing window: Process ID=%08Xh against %08Xh",
processId,
p->ProcessId
));
if (match) {
p->Match = hwnd;
#ifdef DEBUG
//
// Get the window title for the following debug message
//
GetWindowTextW (hwnd, title, ARRAYSIZE(title));
DEBUGMSGA ((
DBG_NAUSEA,
"Window found: %s, ID=%u",
title,
processId
));
#endif
return FALSE; // stop enum
}
return TRUE; // continue enum
}
HWND
WndFindWindowInProcessA (
IN DWORD ProcessId,
IN PCSTR WindowTitle OPTIONAL
)
/*++
Routine Description:
Finds a window by enumerating all top-level windows, and checking the
process id. The first one to match the optionally supplied title is used.
Arguments:
ProcessId - Specifies the ID of the process who owns the window. If
zero is specified, NULL is returned.
WindowTitle - Specifies the name of the window to find.
Return Value:
The handle to the matching window, or NULL if no window has the
specified title and process ID.
--*/
{
FINDWINDOW_STRUCTA findWndStruct;
//
// If no process ID, we cannot have a match
//
if (!ProcessId) {
DEBUGMSG ((DBG_WND, "ProcessId == 0"));
return NULL;
}
ZeroMemory (&findWndStruct, sizeof (findWndStruct));
findWndStruct.WindowTitle = WindowTitle;
findWndStruct.ProcessId = ProcessId;
EnumWindows (pEnumWndProcA, (LPARAM) &findWndStruct);
return findWndStruct.Match;
}
HWND
WndFindWindowInProcessW (
IN DWORD ProcessId,
IN PCWSTR WindowTitle OPTIONAL
)
{
FINDWINDOW_STRUCTW findWndStruct;
//
// If no process ID, we cannot have a match
//
if (!ProcessId) {
DEBUGMSG ((DBG_WND, "ProcessId == 0"));
return NULL;
}
ZeroMemory (&findWndStruct, sizeof (findWndStruct));
findWndStruct.WindowTitle = WindowTitle;
findWndStruct.ProcessId = ProcessId;
EnumWindows (pEnumWndProcW, (LPARAM) &findWndStruct);
return findWndStruct.Match;
}
#define WIDTH(rect) (rect.right - rect.left)
#define HEIGHT(rect) (rect.bottom - rect.top)
VOID
WndCenterWindow (
IN HWND hwnd,
IN HWND Parent OPTIONAL
)
{
RECT WndRect, ParentRect;
int x, y;
if (!Parent) {
ParentRect.left = 0;
ParentRect.top = 0;
ParentRect.right = GetSystemMetrics (SM_CXFULLSCREEN);
ParentRect.bottom = GetSystemMetrics (SM_CYFULLSCREEN);
} else {
GetWindowRect (Parent, &ParentRect);
}
MYASSERT (IsWindow (hwnd));
GetWindowRect (hwnd, &WndRect);
x = ParentRect.left + (WIDTH(ParentRect) - WIDTH(WndRect)) / 2;
y = ParentRect.top + (HEIGHT(ParentRect) - HEIGHT(WndRect)) / 2;
SetWindowPos (hwnd, NULL, x, y, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
}
VOID
WndTurnOnWaitCursor (
VOID
)
/*++
Routine Description:
WndTurnOnWaitCursor sets the cursor to IDC_WAIT. It maintains a use
counter, so code requring the wait cursor can be nested.
Arguments:
none
Return Value:
none
--*/
{
if (g_CursorRefCount == 0) {
g_OldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
}
g_CursorRefCount++;
}
VOID
WndTurnOffWaitCursor (
VOID
)
/*++
Routine Description:
WndTurnOffWaitCursor decrements the wait cursor counter, and if it reaches
zero the cursor is restored.
Arguments:
none
Return Value:
none
--*/
{
if (!g_CursorRefCount) {
DEBUGMSG ((DBG_WHOOPS, "TurnOffWaitCursor called too many times"));
} else {
g_CursorRefCount--;
if (!g_CursorRefCount) {
SetCursor (g_OldCursor);
}
}
}
VOID
WndSetWizardButtonsA (
IN HWND PageHandle,
IN DWORD EnableButtons,
IN DWORD DisableButtons,
IN PCSTR AlternateFinishText OPTIONAL
)
{
DWORD flags = 0;
HWND wizardHandle;
wizardHandle = GetParent (PageHandle);
if (EnableButtons & FINISH_BUTTON) {
MYASSERT (!(EnableButtons & CANCEL_BUTTON));
MYASSERT (!(EnableButtons & NEXT_BUTTON));
MYASSERT (!(DisableButtons & CANCEL_BUTTON));
MYASSERT (!(DisableButtons & NEXT_BUTTON));
MYASSERT (!(DisableButtons & FINISH_BUTTON));
EnableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
DisableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
flags |= PSWIZB_FINISH;
}
if (DisableButtons & FINISH_BUTTON) {
MYASSERT (!(EnableButtons & CANCEL_BUTTON));
MYASSERT (!(EnableButtons & NEXT_BUTTON));
MYASSERT (!(DisableButtons & CANCEL_BUTTON));
MYASSERT (!(DisableButtons & NEXT_BUTTON));
EnableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
DisableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
flags |= PSWIZB_DISABLEDFINISH;
}
if (EnableButtons & NEXT_BUTTON) {
MYASSERT (!(DisableButtons & NEXT_BUTTON));
flags |= PSWIZB_NEXT;
}
if (EnableButtons & BACK_BUTTON) {
MYASSERT (!(DisableButtons & BACK_BUTTON));
flags |= PSWIZB_BACK;
}
if (DisableButtons & NEXT_BUTTON) {
flags &= ~PSWIZB_NEXT;
}
if (DisableButtons & BACK_BUTTON) {
flags &= ~PSWIZB_BACK;
}
PropSheet_SetWizButtons (wizardHandle, flags);
if (EnableButtons & CANCEL_BUTTON) {
EnableWindow (GetDlgItem (wizardHandle, IDCANCEL), TRUE);
}
if (DisableButtons & CANCEL_BUTTON) {
EnableWindow (GetDlgItem (wizardHandle, IDCANCEL), FALSE);
}
if (AlternateFinishText) {
if (flags & PSWIZB_FINISH) {
SendMessage (
wizardHandle,
PSM_SETFINISHTEXT,
0,
(LPARAM) AlternateFinishText
);
}
}
}
VOID
WndSetWizardButtonsW (
IN HWND PageHandle,
IN DWORD EnableButtons,
IN DWORD DisableButtons,
IN PCWSTR AlternateFinishText OPTIONAL
)
{
PCSTR ansiText;
if (AlternateFinishText) {
ansiText = ConvertWtoA (AlternateFinishText);
WndSetWizardButtonsA (PageHandle, EnableButtons, DisableButtons, ansiText);
FreeConvertedStr (ansiText);
} else {
WndSetWizardButtonsA (PageHandle, EnableButtons, DisableButtons, NULL);
}
}