Windows-Server-2003/inetcore/setup/active/iernonce/roexui.cpp

433 lines
12 KiB
C++

// **************************************************************************
//
// RunOnce.Cpp
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1992-1993
// All rights reserved
//
// RunOnce wrapper. This encapsulates all applications that would like
// to run the first time we re-boot. It lists these apps for the user
// and allows the user to launce the apps (like apple at ease).
//
// 5 June 1994 FelixA Started
// 8 June Felix Defined registry strings and functionality.
// Got small buttons displayed, but not working.
// 9 June Felix Both big and small buttons. Nice UI.
// Got single click app launching.
//
// 23 June Felix Moving it to a Chicago make thingy not Dolphin
//
// *************************************************************************/
//
#include "iernonce.h"
#include "resource.h"
#define CXBORDER 3
// globals
HDC g_hdcMem = NULL; // Run time can be set for big or small buttons.
int g_cxSmIcon = 0; // Icon sizes.
SIZE g_SizeTextExt; // Extent of text in buttons.
HFONT g_hfont = NULL;
HFONT g_hBoldFont = NULL;
HBRUSH g_hbrBkGnd = NULL;
ARGSINFO g_aiArgs;
// prototypes
BOOL CreateGlobals(HWND hwndCtl);
BOOL RunOnceFill(HWND hWndLB);
void ShrinkToFit(HWND hWnd, HWND hLb);
DWORD RunAppsInList(LPVOID lp);
LRESULT HandleLBMeasureItem(HWND hwndLB, MEASUREITEMSTRUCT *lpmi);
LRESULT HandleLBDrawItem(HWND hwndLB, DRAWITEMSTRUCT *lpdi);
void DestroyGlobals(void);
INT_PTR CALLBACK DlgProcRunOnceEx(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HANDLE s_hThread = NULL;
DWORD dwThread;
switch (uMsg)
{
case WM_INITDIALOG:
g_aiArgs = *((ARGSINFO *) lParam);
CreateGlobals(hWnd);
SetWindowPos(hWnd, NULL, 32, 32, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
RunOnceFill(GetDlgItem(hWnd, IDC_LIST2));
// Now calculate the size needed for the LB and resize LB and parent.
ShrinkToFit(hWnd, GetDlgItem(hWnd, IDC_LIST2));
if ((s_hThread = CreateThread(NULL, 0, RunAppsInList, (LPVOID) GetDlgItem(hWnd, IDC_LIST2), 0, &dwThread)) == NULL)
PostMessage(hWnd, WM_FINISHED, 0, 0L);
break;
case WM_SETCURSOR:
if (g_aiArgs.dwFlags & RRA_WAIT)
SetCursor(LoadCursor(NULL, IDC_WAIT));
return TRUE;
case WM_MEASUREITEM:
if (((MEASUREITEMSTRUCT *) lParam)->CtlType == ODT_LISTBOX)
return HandleLBMeasureItem(hWnd, (MEASUREITEMSTRUCT *) lParam);
else
return FALSE;
case WM_DRAWITEM:
if (((DRAWITEMSTRUCT *) lParam)->CtlType == ODT_LISTBOX)
return HandleLBDrawItem(hWnd, (DRAWITEMSTRUCT *) lParam);
else
return FALSE;
case WM_CTLCOLORLISTBOX:
SetTextColor((HDC) wParam, GetSysColor(COLOR_BTNTEXT));
SetBkColor((HDC) wParam, GetSysColor(COLOR_BTNFACE));
return (LRESULT) g_hbrBkGnd;
case WM_FINISHED:
if (s_hThread != NULL)
{
while (MsgWaitForMultipleObjects(1, &s_hThread, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CloseHandle(s_hThread);
s_hThread = NULL;
}
DestroyGlobals();
EndDialog(hWnd, 0);
break;
default:
return FALSE;
}
return TRUE;
}
LPSTR MakeAnsiStrFromWide(LPWSTR pwsz)
{
LPSTR psz;
int i;
// arg checking.
//
if (!pwsz)
return NULL;
// compute the length
//
i = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, NULL, 0, NULL, NULL);
if (i <= 0) return NULL;
psz = (LPSTR) CoTaskMemAlloc(i * sizeof(CHAR));
if (!psz) return NULL;
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, i, NULL, NULL);
psz[i - 1] = 0;
return psz;
}
BOOL CreateGlobals(HWND hwndCtl)
{
LOGFONT lf;
HDC hdc;
HFONT hfontOld;
g_cxSmIcon = GetSystemMetrics(SM_CXSMICON);
g_hbrBkGnd = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
if ((hfontOld = (HFONT) (WORD) SendMessage(hwndCtl, WM_GETFONT, 0, 0L)) != NULL)
{
if (GetObject(hfontOld, sizeof(LOGFONT), (LPSTR) &lf))
{
// The CreateFontIndirect calls in IESetup Wzd works correctly on
// all platforms... and they convert the Font name to Ansi
// Hence to solve the Thai NT/Thai Win9x problem, we also convert
// the font name to Ansi before calling CreateFontIndirect.
// #58923: Now the FaceName returned by GetObject is not UNICODE on all
// platforms. On Win9x, it is Ansi and this screws up things when
// we call MakeAnsiStrFromWide on it. Hence to avoid problems, check
// if returned FaceName is Wide <asumming FaceName always has more
// than 2 chars in it.>
if (lf.lfFaceName[1] == '\0')
{
LPSTR pszAnsiName;
pszAnsiName = MakeAnsiStrFromWide((unsigned short *)lf.lfFaceName);
lstrcpy((char *)lf.lfFaceName, pszAnsiName);
CoTaskMemFree((LPVOID)pszAnsiName);
}
lf.lfWeight = 400;
g_hfont = CreateFontIndirect(&lf);
lf.lfWeight = 700;
g_hBoldFont = CreateFontIndirect(&lf);
}
}
if (g_hfont)
{
TCHAR *szLotsaWs = TEXT("WWWWWWWWWW");
// Calc sensible size for text in buttons.
hdc = GetDC(NULL);
hfontOld = (HFONT) SelectObject(hdc, g_hfont);
GetTextExtentPoint(hdc, szLotsaWs, lstrlen(szLotsaWs), &g_SizeTextExt);
SelectObject(hdc, hfontOld);
ReleaseDC(NULL, hdc);
return TRUE;
}
return FALSE;
}
//***************************************************************************
//
// RunOnceFill()
// Fills the List box in the run-once dlg.
//
// ENTRY:
// HWND of the thing to fill.
//
// EXIT:
// <Params>
//
//***************************************************************************
BOOL RunOnceFill(HWND hWndLB)
{
RunOnceExSection *pCurrentRunOnceExSection;
int iSectionIndex;
// if Title value is present, display it
if (*g_szTitleString)
SetWindowText(GetParent(hWndLB), g_szTitleString);
for (iSectionIndex = 0; iSectionIndex < g_aiArgs.iNumberOfSections; iSectionIndex++)
{
pCurrentRunOnceExSection = (RunOnceExSection *) DPA_GetPtr(g_aiArgs.hdpaSections, iSectionIndex);
if (*pCurrentRunOnceExSection->m_szDisplayName != TEXT('\0'))
SendMessage(hWndLB, LB_ADDSTRING, 0, (LPARAM) pCurrentRunOnceExSection->m_szDisplayName);
}
return TRUE;
}
//***************************************************************************
//
// ShrinkToFit()
// Makes the List box no bigger then it has to be
// makes the parent window rsize to the LB size.
//
// ENTRY:
// hwnd Parent
// hwnd List box
//
// EXIT:
//
//***************************************************************************
void ShrinkToFit(HWND hWnd, HWND hLb)
{
LONG lCount;
LONG lNumItems;
LONG lTotalHeight;
LONG lHeight;
RECT rWnd;
LONG lChange;
lTotalHeight = 0;
lNumItems = (LONG)SendMessage(hLb, LB_GETCOUNT, 0, 0L);
for (lCount = 0; lCount < lNumItems; lCount++)
{
lHeight = (LONG)SendMessage(hLb, LB_GETITEMHEIGHT, lCount, 0L);
lTotalHeight += lHeight;
}
// Set the height of the ListBox to the number of items in it.
GetWindowRect(hLb, &rWnd);
SetWindowPos(hLb, hWnd, 0, 0, rWnd.right - rWnd.left - (CXBORDER * 2 + g_cxSmIcon), lTotalHeight, SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER);
// Work out how much it changed in height
lChange = lTotalHeight - (rWnd.bottom - rWnd.top);
// Size the parent to fit around the child.
GetWindowRect(hWnd, &rWnd);
SetWindowPos(hWnd, 0, 0, 0, rWnd.right - rWnd.left, rWnd.bottom - rWnd.top + lChange, SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER);
}
//***************************************************************************
//
// RunAppsInList()
// Enumerates all the items in the list box, spawning each in turn.
//
// ENTRY:
// HWND of Parent.
//
// EXIT:
// <Params>
//
//***************************************************************************
DWORD RunAppsInList(LPVOID lp)
{
ProcessSections(g_aiArgs.hkeyParent, g_aiArgs.pszSubkey, g_aiArgs.dwFlags, g_aiArgs.hdpaSections, g_aiArgs.iNumberOfSections, (HWND) lp);
// terminate the dialog box
PostMessage(GetParent((HWND) lp), WM_FINISHED, 0, 0L);
return 0;
}
LRESULT HandleLBMeasureItem(HWND hDlg, MEASUREITEMSTRUCT *lpmi)
{
RECT rWnd;
int wWnd;
HDC hDC;
HFONT hfontOld;
TCHAR szText[MAX_ENTRYNAME];
// Get the Height and Width of the child window
GetWindowRect(hDlg, &rWnd);
wWnd = rWnd.right - rWnd.left;
lpmi->itemWidth = wWnd;
hDC = GetDC(NULL);
if ((hfontOld = (HFONT) SelectObject(hDC, g_hBoldFont)) != 0)
{
rWnd.top = 0;
rWnd.left = CXBORDER * 2 + g_cxSmIcon;
rWnd.right = lpmi->itemWidth - rWnd.left - CXBORDER * 2 - g_cxSmIcon;
rWnd.bottom = 0;
*szText = TEXT('\0');
SendMessage(GetDlgItem(hDlg, IDC_LIST2), LB_GETTEXT, (WPARAM) lpmi->itemID, (LPARAM) szText);
DrawText(hDC, szText, lstrlen(szText), &rWnd, DT_CALCRECT | DT_WORDBREAK);
SelectObject(hDC, hfontOld);
}
ReleaseDC(NULL, hDC);
lpmi->itemHeight = rWnd.bottom + CXBORDER * 2;
return TRUE;
}
//***************************************************************************
//
// HandleLBDrawItem()
// Draws the Title, Text, and icon for an entry.
//
// ENTRY:
// HWND and the Item to draw.
//
// EXIT:
// <Params>
//
//***************************************************************************
LRESULT HandleLBDrawItem(HWND hDlg, DRAWITEMSTRUCT *lpdi)
{
RECT rc;
HFONT hfontOld;
int xArrow,y;
BITMAP bm;
HGDIOBJ hbmArrow, hbmOld;
TCHAR szText[MAX_ENTRYNAME];
// Don't draw anything for an empty list.
if ((int) lpdi->itemID < 0)
return TRUE;
if ((lpdi->itemAction & ODA_SELECT) || (lpdi->itemAction & ODA_DRAWENTIRE))
{
// Put in the Title text
hfontOld = (HFONT) SelectObject(lpdi->hDC, (lpdi->itemState & ODS_SELECTED) ? g_hBoldFont : g_hfont);
ExtTextOut(lpdi->hDC, lpdi->rcItem.left + CXBORDER * 2 + g_cxSmIcon, lpdi->rcItem.top + CXBORDER,
ETO_OPAQUE, &lpdi->rcItem, NULL, 0, NULL);
rc.top = lpdi->rcItem.top + CXBORDER;
rc.left = lpdi->rcItem.left + CXBORDER * 2 + g_cxSmIcon;
rc.right = lpdi->rcItem.right;
rc.bottom = lpdi->rcItem.bottom;
*szText = TEXT('\0');
SendMessage(GetDlgItem(hDlg, IDC_LIST2), LB_GETTEXT, (WPARAM) lpdi->itemID, (LPARAM) szText);
DrawText(lpdi->hDC, szText, lstrlen(szText), &rc, DT_WORDBREAK);
SelectObject(lpdi->hDC, hfontOld);
// Draw the little triangle thingies.
if (lpdi->itemState & ODS_SELECTED)
{
if (!g_hdcMem)
{
g_hdcMem = CreateCompatibleDC(lpdi->hDC);
}
if (g_hdcMem)
{
hbmArrow = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_MNARROW));
GetObject(hbmArrow, sizeof(bm), &bm);
hbmOld = SelectObject(g_hdcMem, hbmArrow);
xArrow = lpdi->rcItem.left + CXBORDER;
y = ((g_SizeTextExt.cy - bm.bmHeight) / 2) + CXBORDER + lpdi->rcItem.top;
BitBlt(lpdi->hDC, xArrow, y, bm.bmWidth, bm.bmHeight, g_hdcMem, 0, 0, SRCAND);
SelectObject(g_hdcMem, hbmOld);
DeleteObject(hbmArrow);
}
}
}
return TRUE;
}
void DestroyGlobals(void)
{
if (g_hfont)
{
DeleteObject(g_hfont);
g_hfont = NULL;
}
if (g_hBoldFont)
{
DeleteObject(g_hBoldFont);
g_hBoldFont = NULL;
}
if (g_hbrBkGnd)
{
DeleteObject(g_hbrBkGnd);
g_hbrBkGnd = NULL;
}
}