You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
807 lines
24 KiB
807 lines
24 KiB
// **************************************************************************
|
|
//
|
|
// Status.C
|
|
//
|
|
// Microsoft Confidential
|
|
// Copyright (c) Microsoft Corporation 1999-2001
|
|
// All rights reserved
|
|
//
|
|
// This application implements a common status dialog for factory functions.
|
|
//
|
|
// 04/01/2001 Stephen Lodwick
|
|
// Project started
|
|
//
|
|
//
|
|
// *************************************************************************/
|
|
|
|
//
|
|
// Includes
|
|
//
|
|
#include "factoryp.h"
|
|
|
|
|
|
typedef struct _STATUSWINDOWS
|
|
{
|
|
HWND hStatusWindow;
|
|
LPSTATUSNODE lpCurrent;
|
|
struct _STATUSWINDOWS*lpNext;
|
|
} STATUSWINDOWS, *LPSTATUSWINDOWS, **LPLPSTATUSWINDOWS;
|
|
|
|
typedef struct _DIALOGPARAM
|
|
{
|
|
LPSTATUSWINDOW lpswParam;
|
|
LPSTATUSNODE lpsnParam;
|
|
HWND hStatusWindow;
|
|
HANDLE hEvent;
|
|
} DIALOGPARAM, *LPDIALOGPARAM, **LPLPDIALOGPARAM;
|
|
|
|
//
|
|
// Internal Function Prototype(s):
|
|
//
|
|
LRESULT CALLBACK StatusDlgProc(HWND, UINT, WPARAM, LPARAM);
|
|
DWORD StatusDisplayList(HWND, LPSTATUSNODE);
|
|
BOOL StatusAddWindow(HWND, LPLPSTATUSWINDOWS, LPSTATUSNODE, BOOL);
|
|
VOID StatusCreateDialogThread(LPDIALOGPARAM);
|
|
|
|
//
|
|
// Internal Define(s):
|
|
//
|
|
#define FIRST_SPACING 7 // Spacing (pixel) between the title and the first app
|
|
#define LINE_SPACING 7 // Spacing (pixel) between additional applcations
|
|
|
|
#define WM_FINISHED (WM_USER + 0x0001) // User defined message to indicate the dialog should be destroyed
|
|
#define WM_PROGRESS (WM_USER + 0x0002) // User defined message to indicate that we are progressing to the next app
|
|
|
|
|
|
/*++
|
|
|
|
Routine:
|
|
StatusAddNode
|
|
|
|
Routine Description:
|
|
|
|
This routine takes a string and adds that string onto the end of our
|
|
linked list.
|
|
|
|
Arguments:
|
|
|
|
lpszNodeText - Pointer to string of text that you would like to add to list
|
|
lplpsnHead - Pointer to a LPSTATUSNODE list
|
|
|
|
Return Value:
|
|
|
|
TRUE - Node was added to list
|
|
FALSE - If the Node was not added to list
|
|
|
|
--*/
|
|
BOOL StatusAddNode(
|
|
LPTSTR lpszNodeText, // Text that you would like to add to the current list
|
|
LPLPSTATUSNODE lplpsnHead // List that we will be adding status node to
|
|
)
|
|
{
|
|
LPSTATUSNODE lpsnTemp = NULL;
|
|
|
|
if ( lpszNodeText && *lpszNodeText == NULLCHR )
|
|
return FALSE;
|
|
|
|
// Go to the end of the list
|
|
//
|
|
while ( lplpsnHead && *lplpsnHead )
|
|
lplpsnHead=&((*lplpsnHead)->lpNext);
|
|
|
|
if ( (lpsnTemp = (LPSTATUSNODE)MALLOC(sizeof(STATUSNODE)) ) && lpszNodeText )
|
|
{
|
|
lstrcpyn(lpsnTemp->szStatusText, lpszNodeText, AS( lpsnTemp->szStatusText ) );
|
|
lpsnTemp->lpNext = NULL;
|
|
|
|
// Make sure the previous node points to the new node
|
|
//
|
|
if ( lplpsnHead )
|
|
*lplpsnHead = lpsnTemp;
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine:
|
|
StatusIncrement
|
|
|
|
Routine Description:
|
|
|
|
This routine increments the status to the next node in the list
|
|
|
|
Arguments:
|
|
|
|
hStatusDialog - Handle of the StatusDialog
|
|
bLastResult - Result of the last node (whether it succeeded or failed)
|
|
|
|
Return Value:
|
|
|
|
TRUE - Message sent to status dialog
|
|
FALSE - Message was not sent to status dialog
|
|
|
|
--*/
|
|
BOOL StatusIncrement(
|
|
HWND hStatusDialog,
|
|
BOOL bLastResult
|
|
)
|
|
{
|
|
// We must have a valid handle to the status dialog
|
|
//
|
|
if ( IsWindow(hStatusDialog) )
|
|
{
|
|
// Send a message to the dialog proc to go to the next caption
|
|
//
|
|
SendMessage(hStatusDialog, WM_PROGRESS,(WPARAM) NULL,(LPARAM) bLastResult);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine:
|
|
StatusEndDialog
|
|
|
|
Routine Description:
|
|
|
|
This routine sends a message to a status dialog to end.
|
|
|
|
Arguments:
|
|
|
|
hStatusDialog - Handle of the StatusDialog
|
|
|
|
Return Value:
|
|
|
|
TRUE - Message sent to status dialog
|
|
FALSE - Message was not sent to status dialog
|
|
|
|
--*/
|
|
BOOL StatusEndDialog(
|
|
HWND hStatusDialog // handle to status dialog
|
|
)
|
|
{
|
|
// We must have a valid handle to the status dialog
|
|
//
|
|
if ( IsWindow(hStatusDialog) )
|
|
{
|
|
// Send a message to the dialog proc to end the dialog
|
|
//
|
|
SendMessage(hStatusDialog, WM_FINISHED,(WPARAM) NULL,(LPARAM) NULL);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine:
|
|
StatusCreateDialogThread
|
|
|
|
Routine Description:
|
|
|
|
This routine creates the dialog for the status window and processes until the window is ended.
|
|
|
|
Arguments:
|
|
|
|
lpDialog - Pointer to structure that contains information to create thread/dialog
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
VOID StatusCreateDialogThread(LPDIALOGPARAM lpDialog)
|
|
{
|
|
MSG msg;
|
|
HWND hWnd;
|
|
HANDLE hEvent = lpDialog->hEvent;
|
|
|
|
hWnd = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_RUN), NULL, StatusDlgProc, (LPARAM) lpDialog);
|
|
|
|
while (GetMessage(&msg, hWnd, 0, 0) != 0)
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
// Event has not been been signaled, null out the hwnd and signal event
|
|
//
|
|
if ( WaitForSingleObject(hEvent, 0) == WAIT_TIMEOUT )
|
|
{
|
|
// Reset the status window handle to null, and set the event
|
|
//
|
|
lpDialog->hStatusWindow = NULL;
|
|
SetEvent(lpDialog->hEvent);
|
|
}
|
|
else
|
|
{
|
|
// Close the event handle
|
|
//
|
|
CloseHandle(hEvent);
|
|
}
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine:
|
|
StatusCreateDialog
|
|
|
|
Routine Description:
|
|
|
|
Main function that creates the status dialog
|
|
|
|
Arguments:
|
|
|
|
lpswStatus - Pointer to structure that contains information about Status Window
|
|
lpsnStatus - Pointer to struction that contains head node for status labels
|
|
|
|
Return Value:
|
|
|
|
HWND - Handle to window that was created, NULL if window was not created.
|
|
|
|
--*/
|
|
HWND StatusCreateDialog(
|
|
LPSTATUSWINDOW lpswStatus, // structure that contains information about the window
|
|
LPSTATUSNODE lpsnStatus // head node for status text
|
|
)
|
|
{
|
|
DIALOGPARAM dpStatus;
|
|
DWORD dwThread;
|
|
HANDLE hThread;
|
|
HANDLE hEvent;
|
|
|
|
// Determine if we have the required structures to continue, an hInstance, and some status text
|
|
//
|
|
if ( !lpswStatus || !lpsnStatus || !lpsnStatus->szStatusText[0])
|
|
return NULL;
|
|
|
|
// Zero out memory
|
|
//
|
|
ZeroMemory(&dpStatus, sizeof(dpStatus));
|
|
|
|
// Create an event, non-signaled to determine if dialog is initialized
|
|
//
|
|
if ( hEvent = CreateEvent(NULL, TRUE, FALSE, NULL) )
|
|
{
|
|
// Need a single variable for the dialog box parameter
|
|
//
|
|
dpStatus.lpswParam = lpswStatus;
|
|
dpStatus.lpsnParam = lpsnStatus;
|
|
dpStatus.hStatusWindow = NULL;
|
|
dpStatus.hEvent = hEvent;
|
|
|
|
|
|
// Create the thread to initialize the dialog
|
|
//
|
|
if (hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) StatusCreateDialogThread, (LPVOID) &dpStatus, 0, &dwThread) )
|
|
{
|
|
MSG msg;
|
|
|
|
// Wait for the event from WM_INITDIALOG
|
|
//
|
|
WaitForSingleObject(hEvent, INFINITE);
|
|
|
|
// Close the handle to the thread
|
|
//
|
|
CloseHandle(hThread);
|
|
}
|
|
|
|
// Reset and close the event only if we failed to create window, otherwise, StatusCreateDialogThread will close handle
|
|
//
|
|
if ( !dpStatus.hStatusWindow )
|
|
CloseHandle(hEvent);
|
|
}
|
|
|
|
// Return the handle to the StatusDialog
|
|
//
|
|
return ( dpStatus.hStatusWindow );
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine:
|
|
StatusDlgProc
|
|
|
|
Routine Description:
|
|
|
|
Main dialog procedure for StatusCreateDialog.
|
|
|
|
Arguments:
|
|
|
|
hWnd - Handle to window
|
|
uMsg - Message being sent to window
|
|
uParam - Upper parameter being sent
|
|
lParam - Lower parameter being sent
|
|
|
|
Return Value:
|
|
|
|
LRESULT - Result of message that was processed
|
|
|
|
--*/
|
|
LRESULT CALLBACK StatusDlgProc(HWND hWnd, UINT uMsg, WPARAM uParam, LPARAM lParam)
|
|
{
|
|
static HFONT hNormFont = NULL;
|
|
static HFONT hBoldFont = NULL;
|
|
static HANDLE hIconSuccess = NULL;
|
|
static HANDLE hIconError = NULL;
|
|
static LPSTATUSWINDOWS lpStatusWindows;
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
LPSTATUSWINDOW lpswWindow = NULL;
|
|
LPSTATUSNODE lpHead = NULL,
|
|
lpWindowHead = NULL;
|
|
HANDLE hEvent = NULL;
|
|
|
|
if ( lParam )
|
|
{
|
|
// Determine the window, and current node
|
|
//
|
|
lpswWindow = ((LPDIALOGPARAM)lParam)->lpswParam;
|
|
lpHead = ((LPDIALOGPARAM)lParam)->lpsnParam;
|
|
hEvent = ((LPDIALOGPARAM)lParam)->hEvent;
|
|
|
|
// Check to make sure that we have pointers to the required structures
|
|
//
|
|
if ( !lpswWindow || !lpHead || !hEvent)
|
|
{
|
|
PostMessage(hWnd, WM_FINISHED,(WPARAM) NULL,(LPARAM) NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
// Copy the list that was passed in, to our own buffer
|
|
//
|
|
while ( lpHead )
|
|
{
|
|
StatusAddNode(lpHead->szStatusText, &lpWindowHead);
|
|
lpHead = lpHead->lpNext;
|
|
}
|
|
|
|
// Add this window to our list of windows
|
|
//
|
|
StatusAddWindow(hWnd, &lpStatusWindows, lpWindowHead, FALSE);
|
|
|
|
// Set the status window if there is one specified
|
|
//
|
|
if (lpswWindow->szWindowText[0] )
|
|
SetWindowText(hWnd, lpswWindow->szWindowText);
|
|
|
|
// Set the status window description if there is one specified.
|
|
//
|
|
if ( lpswWindow->lpszDescription )
|
|
{
|
|
SetDlgItemText(hWnd, IDC_TITLE, lpswWindow->lpszDescription);
|
|
}
|
|
|
|
// Set the status window description if there is one specified.
|
|
//
|
|
if ( lpswWindow->hMainIcon )
|
|
{
|
|
SendDlgItemMessage(hWnd, IDC_STATUS_ICON, STM_SETICON, (WPARAM) lpswWindow->hMainIcon, 0L);
|
|
}
|
|
|
|
// Display the list
|
|
//
|
|
StatusDisplayList(hWnd, lpWindowHead);
|
|
|
|
// Move the window if a position was given
|
|
//
|
|
if ( lpswWindow->X || lpswWindow->Y )
|
|
{
|
|
// See if either coordinate is relative to the other
|
|
// side of the screen.
|
|
//
|
|
if ( ( lpswWindow->X < 0 ) ||
|
|
( lpswWindow->Y < 0 ) )
|
|
{
|
|
RECT rc;
|
|
|
|
// Need to get the size of our work area on the main monitor.
|
|
//
|
|
if ( SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0) )
|
|
{
|
|
RECT rcHwnd;
|
|
POINT point;
|
|
|
|
// This code will get the current window size/position,
|
|
// set the point structure to the upper left coordinate
|
|
// for the window if we wanted the lower right part of
|
|
// window to touch the lower right part of the desktop.
|
|
//
|
|
GetWindowRect(hWnd, &rcHwnd);
|
|
point.x = rc.right - (rcHwnd.right - rcHwnd.left);
|
|
point.y = rc.bottom - (rcHwnd.bottom - rcHwnd.top);
|
|
MapWindowPoints(NULL, hWnd, &point, 1);
|
|
|
|
// Now if they passed in negative coordinates, add those
|
|
// to our point structure so the window moves away from
|
|
// the bottom or right part of the screen by the number
|
|
// of units they specifed.
|
|
//
|
|
if ( lpswWindow->X < 0 )
|
|
{
|
|
lpswWindow->X += point.x;
|
|
}
|
|
if ( lpswWindow->Y < 0 )
|
|
{
|
|
lpswWindow->Y += point.y;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now move the window.
|
|
//
|
|
SetWindowPos(hWnd, 0, lpswWindow->X, lpswWindow->Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
|
|
// Build the new fonts
|
|
//
|
|
if(!hNormFont)
|
|
hNormFont = GetFont((HWND) GetDlgItem(hWnd, IDC_TITLE), NULL, 0, FW_NORMAL, FALSE);
|
|
|
|
if(!hBoldFont)
|
|
hBoldFont = GetFont((HWND) GetDlgItem(hWnd, IDC_TITLE), NULL, 0, FW_BOLD, FALSE);
|
|
|
|
// Bold the first item in the list
|
|
//
|
|
if ( lpWindowHead && hBoldFont)
|
|
SendMessage((HWND)lpWindowHead->hLabelWin, WM_SETFONT, (WPARAM) hBoldFont, MAKELPARAM(TRUE, 0));
|
|
|
|
// Now make sure we show the window now.
|
|
//
|
|
ShowWindow(hWnd, SW_SHOW);
|
|
|
|
((LPDIALOGPARAM)lParam)->hStatusWindow = hWnd;
|
|
|
|
// Set event stating that dialog is initialized
|
|
//
|
|
SetEvent(hEvent);
|
|
}
|
|
else
|
|
PostMessage(hWnd, WM_FINISHED,(WPARAM) NULL,(LPARAM) NULL);
|
|
}
|
|
break;
|
|
|
|
case WM_PROGRESS:
|
|
{
|
|
// Progress to the next item, if there are no items, end the dialog
|
|
//
|
|
LPSTATUSWINDOWS lpswNext = lpStatusWindows;
|
|
BOOL bFound = FALSE;
|
|
LPSTATUSNODE lpsnTemp = NULL;
|
|
|
|
|
|
// Locate the current node given a window handle
|
|
//
|
|
while ( lpswNext && !bFound)
|
|
{
|
|
if ( lpswNext->hStatusWindow == hWnd )
|
|
bFound = TRUE;
|
|
else
|
|
lpswNext = lpswNext->lpNext;
|
|
}
|
|
|
|
// If there is a current node, lets unbold it, increment and bold the next item
|
|
//
|
|
if ( bFound && lpswNext && lpswNext->lpCurrent )
|
|
{
|
|
if ( hNormFont )
|
|
SendMessage((HWND)lpswNext->lpCurrent->hLabelWin, WM_SETFONT, (WPARAM) hNormFont, MAKELPARAM(TRUE, 0));
|
|
|
|
if ( !hIconSuccess )
|
|
hIconSuccess = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_STATUSSUCCESS), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
|
|
|
|
if ( !hIconError )
|
|
hIconError = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_STATUSERROR), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
|
|
|
|
if ( hIconSuccess && hIconError )
|
|
SendMessage(lpswNext->lpCurrent->hIconWin,STM_SETIMAGE, (WPARAM)IMAGE_ICON, (BOOL)lParam ? (LPARAM)hIconSuccess : (LPARAM)hIconError );
|
|
|
|
// Increment to the next node in the list
|
|
//
|
|
lpsnTemp = lpswNext->lpCurrent;
|
|
lpswNext->lpCurrent = lpswNext->lpCurrent->lpNext;
|
|
|
|
// Free this memory since we allocated it
|
|
//
|
|
FREE(lpsnTemp);
|
|
|
|
// If there is not a current node, end the dialog, otherwise, bold the item
|
|
//
|
|
if ( lpswNext->lpCurrent && hBoldFont)
|
|
SendMessage(lpswNext->lpCurrent->hLabelWin, WM_SETFONT, (WPARAM) hBoldFont, MAKELPARAM(TRUE, 0));
|
|
}
|
|
}
|
|
break;
|
|
case WM_FINISHED:
|
|
{
|
|
// Destroy the dialog
|
|
//
|
|
if ( hWnd )
|
|
{
|
|
// If there are status windows, let's remove the one that we are ending
|
|
//
|
|
if ( lpStatusWindows )
|
|
StatusAddWindow(hWnd, &lpStatusWindows, NULL, TRUE);
|
|
|
|
// Check to see if there are any windows left, if not, do some clean up
|
|
//
|
|
if ( !lpStatusWindows )
|
|
{
|
|
// Delete fonts static to dlgproc
|
|
//
|
|
if (hNormFont)
|
|
{
|
|
DeleteObject(hNormFont);
|
|
hNormFont = NULL;
|
|
}
|
|
|
|
if (hBoldFont)
|
|
{
|
|
DeleteObject(hBoldFont);
|
|
hBoldFont = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
// Quit and end the dialog
|
|
//
|
|
EndDialog(hWnd, 1);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine:
|
|
StatusDisplayList
|
|
|
|
Routine Description:
|
|
|
|
Function that displays list to user interface
|
|
|
|
Arguments:
|
|
|
|
hWnd - Handle to Status window
|
|
lpsnList - List to head Status Node
|
|
|
|
Return Value:
|
|
|
|
DWORD - Number of entries that were added to the dialog
|
|
|
|
--*/
|
|
DWORD StatusDisplayList(HWND hWnd, LPSTATUSNODE lpsnList)
|
|
{
|
|
LPSTATUSNODE lpsnTempList = lpsnList;
|
|
HWND hWndLabel,
|
|
hWndIcon;
|
|
RECT Rect,
|
|
WindowRect;
|
|
POINT Point;
|
|
DWORD dwEntries = 0;
|
|
HFONT hNormFont = NULL;
|
|
LPTSTR lpTempRunName;
|
|
HDC hdc;
|
|
SIZE size = { 0, 0 };
|
|
LONG nWidestControl;
|
|
|
|
GetWindowRect(GetDlgItem(hWnd, IDC_TITLE), &Rect);
|
|
|
|
Rect.right -= Rect.left; // The width of the control.
|
|
Rect.bottom -= Rect.top; // The height of the control.
|
|
|
|
Point.x = Rect.left;
|
|
Point.y = Rect.top;
|
|
|
|
nWidestControl = Rect.right;
|
|
|
|
MapWindowPoints(NULL, hWnd, &Point, 1);
|
|
|
|
Point.y += FIRST_SPACING;
|
|
|
|
while(lpsnTempList)
|
|
{
|
|
|
|
// Calculate the point of the first label window
|
|
//
|
|
Point.y += Rect.bottom + LINE_SPACING;
|
|
|
|
// Get the size of the text in pixels
|
|
//
|
|
if (hdc = GetWindowDC(hWnd))
|
|
{
|
|
GetTextExtentPoint32(hdc, lpsnTempList->szStatusText, lstrlen(lpsnTempList->szStatusText), &size);
|
|
|
|
if (size.cx > nWidestControl)
|
|
nWidestControl = size.cx;
|
|
|
|
ReleaseDC(hWnd, hdc);
|
|
}
|
|
|
|
// Create the label window
|
|
//
|
|
hWndIcon = CreateWindow(_T("STATIC"), _T(""), WS_CHILD | WS_VISIBLE | SS_ICON | SS_CENTERIMAGE, Point.x - 16, Point.y - 2, 16, 16, hWnd, NULL, g_hInstance, NULL);
|
|
hWndLabel = CreateWindow(_T("STATIC"), _T(""), WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE, Point.x, Point.y, (Rect.right > size.cx ? Rect.right : size.cx) , Rect.bottom, hWnd, NULL, g_hInstance, NULL);
|
|
|
|
// If the font is NULL, get a font
|
|
//
|
|
if ( hNormFont == NULL )
|
|
hNormFont = (HFONT) SendDlgItemMessage(hWnd, IDC_TITLE, WM_GETFONT, 0, 0L);
|
|
|
|
// Set the font to the same font as the title
|
|
//
|
|
SendMessage(hWndLabel, WM_SETFONT, (WPARAM) hNormFont, MAKELPARAM(FALSE, 0));
|
|
|
|
// Set the Window text to the name of the program
|
|
//
|
|
SetWindowText(hWndLabel, lpsnTempList->szStatusText);
|
|
|
|
// Set the hWndTemp (created from CreateWindow) in the list
|
|
//
|
|
lpsnTempList->hLabelWin = hWndLabel;
|
|
lpsnTempList->hIconWin = hWndIcon;
|
|
|
|
// Goto the next item in the list
|
|
//
|
|
lpsnTempList = lpsnTempList->lpNext;
|
|
|
|
// Increment for each of the applications in the list
|
|
//
|
|
dwEntries++;
|
|
}
|
|
|
|
GetWindowRect(hWnd, &WindowRect);
|
|
|
|
WindowRect.right = WindowRect.right - WindowRect.left + nWidestControl - Rect.right; // The width of the winodw.
|
|
WindowRect.bottom -= WindowRect.top; // The height of the window.
|
|
|
|
// Resize the dialog to fit the label text.
|
|
//
|
|
SetWindowPos(hWnd, 0, 0, 0, WindowRect.right, WindowRect.bottom + ((Rect.bottom + LINE_SPACING)*dwEntries), SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER );
|
|
|
|
return dwEntries;
|
|
}
|
|
|
|
|
|
/*++
|
|
===============================================================================
|
|
Routine Description:
|
|
|
|
StatusAddWindow
|
|
|
|
Adds a new window to the list. This function is used internally for the status
|
|
dialog.
|
|
|
|
Arguments:
|
|
|
|
hStatusWindow - Handle to Status Window
|
|
lplpswHead - Head of the Windows list
|
|
lpsnHead - Current head node for Status Window
|
|
bRemove - Indicates wheter we add or remove the window from the list
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
===============================================================================
|
|
--*/
|
|
BOOL StatusAddWindow(
|
|
HWND hStatusWindow, // Text that you would like to add to the current list
|
|
LPLPSTATUSWINDOWS lplpswHead, // List that we will be adding status window to
|
|
LPSTATUSNODE lpsnHead, // Head of the STATUSNODE structure
|
|
BOOL bRemove // Indicates if we are removing the window from our list
|
|
)
|
|
{
|
|
LPLPSTATUSWINDOWS lplpswNext = lplpswHead;
|
|
LPSTATUSWINDOWS lpswTemp = NULL;
|
|
LPSTATUSNODE lpsnTemp = NULL;
|
|
BOOL bFound = FALSE;
|
|
|
|
// If there is no status window we have nothing to add
|
|
//
|
|
if ( !hStatusWindow )
|
|
return FALSE;
|
|
|
|
// Attempt to find the window passed in, if not, we are at the end of the list
|
|
//
|
|
while ( *lplpswNext && !bFound)
|
|
{
|
|
if ( (*lplpswNext)->hStatusWindow == hStatusWindow )
|
|
bFound = TRUE;
|
|
else
|
|
lplpswNext=&((*lplpswNext)->lpNext);
|
|
|
|
}
|
|
|
|
// If we are adding it and we didn't find it in the list go ahead an add the new node
|
|
//
|
|
if ( !bRemove && !bFound)
|
|
{
|
|
|
|
if ( lpswTemp = (LPSTATUSWINDOWS)MALLOC(sizeof(STATUSWINDOWS)) )
|
|
{
|
|
lpswTemp->hStatusWindow = hStatusWindow;
|
|
lpswTemp->lpNext = NULL;
|
|
lpswTemp->lpCurrent = lpsnHead;
|
|
|
|
// Make sure the previous node points to the new node
|
|
//
|
|
*lplpswNext = lpswTemp;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
else if ( bRemove && bFound && *lplpswNext)
|
|
{
|
|
// If there are nodes left in for the window, lets clean them up
|
|
//
|
|
if ( (*lplpswNext)->lpCurrent )
|
|
StatusDeleteNodes((*lplpswNext)->lpCurrent);
|
|
|
|
// Free the window node
|
|
//
|
|
lpswTemp = (*lplpswNext);
|
|
(*lplpswNext) = (*lplpswNext)->lpNext;
|
|
FREE(lpswTemp);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*++
|
|
===============================================================================
|
|
Routine Description:
|
|
|
|
VOID StatusDeleteNodes
|
|
|
|
Deletes all the Nodes in a STATUSNODE list
|
|
|
|
Arguments:
|
|
|
|
lpsnHead - current head of the list
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
===============================================================================
|
|
--*/
|
|
VOID StatusDeleteNodes(
|
|
LPSTATUSNODE lpsnHead
|
|
)
|
|
{
|
|
LPSTATUSNODE lpsnTemp = NULL;
|
|
|
|
while ( lpsnHead )
|
|
{
|
|
lpsnTemp = lpsnHead;
|
|
lpsnHead = lpsnHead->lpNext;
|
|
FREE(lpsnTemp);
|
|
}
|
|
}
|