// ************************************************************************** // // rodlg.c // // 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 "precomp.h" #include #include #include #include #include #include // #include extern int g_iState; // Command line args. extern HINSTANCE g_hInst; // current instance #define WM_FINISHED (WM_USER+0x123) #include "resource.h" int g_fCleanBoot; TCHAR c_szRunOnce[]=REGSTR_PATH_RUNONCE; TCHAR c_szSetup[]=REGSTR_PATH_SETUP; TCHAR g_szWallpaper[] = TEXT("wallpaper"); TCHAR szTileWall[] = TEXT("TileWallpaper"); TCHAR szFallback[] = TEXT("*DisplayFallback"); const TCHAR c_szTimeChangedRunOnce[] = TEXT("WarnTimeChanged"); //kernel32 and explorer use this // Run time can be set for big or small buttons. int g_Small=0; HDC g_hdcMem=NULL; DWORD g_dwThread; //*************************************************************************** // // () // // // ENTRY: // // // EXIT: // // //*************************************************************************** //*************************************************************************** // // DoAnyRandomOneTimeStuff() // Just a place to toss random stuff for RunOnce app to do. // // ENTRY: // void // // EXIT: // void // //*************************************************************************** void DoAnyRandomOneTimeStuff(void) { HKEY runonce; // remove any time-changed warning added by kernel32 during boot if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRunOnce, 0, KEY_SET_VALUE, &runonce) == ERROR_SUCCESS) { RegDeleteValue(runonce, (LPCTSTR)c_szTimeChangedRunOnce); RegCloseKey(runonce); } } //*************************************************************************** // // RunOnceFill() // Fills the List box in the run-once dlg. // // ENTRY: // HWND of the thing to fill. // // EXIT: // // BOOL NEAR PASCAL RunRegApps(HKEY hkeyParent, LPCSTR szSubkey, BOOL fDelete, BOOL fWait) // //*************************************************************************** BOOL RunOnceFill(HWND hWnd) { HKEY hkey; // HKEY hDescKey; BOOL fShellInit = FALSE; HKEY hkeyParent = HKEY_LOCAL_MACHINE; TCHAR szSubkey[MAX_PATH]; BOOL fDelete=FALSE; BOOL fWait=FALSE; // Enumerate HKLM\Runonce\Setup - *.* StringCchCopy(szSubkey, ARRAYSIZE(szSubkey), c_szRunOnce); StringCchCat(szSubkey, ARRAYSIZE(szSubkey), TEXT("\\Setup")); if (RegOpenKeyEx(hkeyParent, szSubkey, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) { DWORD cbData, cchValue, dwType, i; TCHAR szValueName[MAX_PATH], szCmdLine[MAX_PATH]; LRESULT lRes; DWORD dwNumSubkeys=1, dwNumValues=5; for (i = 0; ; i++) { cchValue = sizeof(szValueName) / sizeof(TCHAR); cbData = sizeof(szCmdLine); if (RegEnumValue(hkey, i, szValueName, &cchValue, NULL, &dwType, (LPBYTE) szCmdLine, &cbData) != ERROR_SUCCESS) break; if (dwType == REG_SZ) { PTASK pTask; pTask = (PTASK)LocalAlloc( LPTR ,sizeof(TASK)); StringCchCopy(pTask->Text, ARRAYSIZE(pTask->Text) - 1, szValueName); StringCchCopy(pTask->Cmd, ARRAYSIZE(pTask->Cmd) - 1, szCmdLine); lRes = SendMessage( hWnd, LB_ADDSTRING, 0, (LPARAM)pTask ); if( lRes == LB_ERR || lRes == LB_ERRSPACE ) { LocalFree(pTask); pTask=NULL; } } } RegCloseKey(hkey); } return(fShellInit); } //*************************************************************************** // // LaunchApp() // Given an index into the list box, will spawn the task, wait for it to // finish. // // ENTRY: // Index into list. // // EXIT: // // //*************************************************************************** int LaunchApp(HWND hWnd, WORD wItem ) { LPTSTR lpszCmdLine; STARTUPINFO startup; #ifndef DEBUG PROCESS_INFORMATION pi; #endif PTASK pTask; RECT rWnd; GetWindowRect(hWnd, &rWnd); SendMessage(hWnd,LB_SETCURSEL,wItem,0); pTask = (PTASK)SendMessage( hWnd, LB_GETITEMDATA, wItem, 0L); if(pTask != (PTASK)LB_ERR ) { lpszCmdLine = &pTask->Cmd[0]; // Now exec it. startup.cb = sizeof(startup); startup.lpReserved = NULL; startup.lpDesktop = NULL; startup.lpTitle = NULL; startup.dwFlags = STARTF_USEPOSITION; // Set start position startup.dwX=rWnd.right+5; startup.dwY=rWnd.top+5; startup.cbReserved2 = 0; startup.lpReserved2 = NULL; #ifdef DEBUG MessageBox(hWnd, lpszCmdLine,TEXT("DebugRun"),MB_OK); #else if (CreateProcess(NULL, lpszCmdLine, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &startup, &pi)) { WaitForSingleObjectEx(pi.hProcess, INFINITE, TRUE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } else { MessageBeep( MB_ICONEXCLAMATION ); } #endif } else { MessageBeep( MB_ICONEXCLAMATION ); } // Remove any selection after the app terminates. SendMessage( hWnd, LB_SETCURSEL, (WPARAM)-1, 0); return FALSE; } //*************************************************************************** // // RunAppsInList() // Enumerates all the items in the list box, spawning each in turn. // // ENTRY: // HWND of Parent. // // EXIT: // // //*************************************************************************** DWORD WINAPI RunAppsInList(LPVOID lp) { HWND hWnd=(HWND)lp; WORD i,iNumItems; TCHAR szSubkey[MAX_PATH]; TCHAR szWallpaper[MAX_PATH]; DWORD cbSize; DWORD dwType; // Run all the applications in the list iNumItems = (WORD)SendMessage(hWnd,LB_GETCOUNT,0,0L); for(i=0;i() // // // ENTRY: // // // EXIT: // // //*************************************************************************** #define CXBORDER 3 LRESULT _HandleLBMeasureItem(HWND hwndLB, MEASUREITEMSTRUCT *lpmi) { RECT rWnd; int wWnd; HDC hDC; HFONT hfontOld; PTASK pTask; // Get the Height and Width of the child window GetWindowRect (hwndLB, &rWnd); wWnd = rWnd.right - rWnd.left; lpmi->itemWidth = wWnd; pTask = (PTASK)lpmi->itemData; hDC= GetDC(NULL); if( (hfontOld = 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; DrawText(hDC,pTask->Text, lstrlen(pTask->Text),&rWnd, DT_CALCRECT | DT_WORDBREAK ); SelectObject(hDC, hfontOld); } ReleaseDC(NULL,hDC); lpmi->itemHeight = rWnd.bottom + 2*CXBORDER; return TRUE; } //--------------------------------------------------------------------------- //*************************************************************************** // // () // // // ENTRY: // // // EXIT: // // //*************************************************************************** LRESULT _HandleMeasureItem(HWND hwnd, MEASUREITEMSTRUCT *lpmi) { if (lpmi->CtlType == ODT_LISTBOX) return _HandleLBMeasureItem(hwnd, lpmi); return TRUE; } //--------------------------------------------------------------------------- //*************************************************************************** // // _HandleLBDrawItem() // Draws the Title, Text, and icon for an entry. // // ENTRY: // HWND and the Item to draw. // // EXIT: // // //*************************************************************************** LRESULT _HandleLBDrawItem(HWND hwndLB, DRAWITEMSTRUCT *lpdi) { RECT rc; HFONT hfontOld; int xArrow,y; PTASK pTask; BITMAP bm; HGDIOBJ hbmArrow,hbmOld; // Don't draw anything for an empty list. if ((int)lpdi->itemID < 0) return TRUE; pTask = (PTASK)lpdi->itemData; if(pTask == (PTASK)LB_ERR || !pTask ) return FALSE; if ((lpdi->itemAction & ODA_SELECT) || (lpdi->itemAction & ODA_DRAWENTIRE)) { // Put in the Title text hfontOld = 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; DrawText( lpdi->hDC, pTask->Text, lstrlen(pTask->Text), &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); } // selected SRCSTENCIL=0x00d8074a // not selected SRCAND. if (g_hdcMem) { hbmArrow = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_MNARROW)); GetObject(hbmArrow, sizeof(bm), &bm); hbmOld = SelectObject(g_hdcMem, hbmArrow); xArrow = lpdi->rcItem.left + CXBORDER; // - bm.bmWidth; 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); // dwRop); SelectObject(g_hdcMem, hbmOld); DeleteObject(hbmArrow); } } } return TRUE; } //--------------------------------------------------------------------------- LRESULT _HandleCtlColorListbox(HWND hwnd, HDC hdc) { SetBkColor(hdc, GetSysColor(COLOR_BTNFACE)); return (LRESULT) g_hbrBkGnd; } //--------------------------------------------------------------------------- LRESULT _HandleDrawItem(HWND hwnd, DRAWITEMSTRUCT *lpdi) { if (lpdi->CtlType == ODT_LISTBOX) return _HandleLBDrawItem(hwnd, lpdi); return TRUE; } //--------------------------------------------------------------------------- LRESULT _HandleDeleteItem(HWND hwnd, DELETEITEMSTRUCT *lpdi) { if(lpdi) if(lpdi->itemData) { LocalFree( (HLOCAL)lpdi->itemData ); return TRUE; } return FALSE; } //*************************************************************************** // // 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; lNumItems = (LONG)SendMessage( hLb, LB_GETCOUNT, 0, 0L ); lTotalHeight =0; for( lCount=0;lCount() // // // ENTRY: // // // EXIT: // // //*************************************************************************** LRESULT CALLBACK dlgProcRunOnce( HWND hWnd, // window handle UINT message, // type of message WPARAM uParam, // additional information LPARAM lParam) // additional information { int wmId, wmEvent; HANDLE hThread; switch (message) { case WM_DELETEITEM: return _HandleDeleteItem( hWnd, (LPDELETEITEMSTRUCT)lParam ); case WM_MEASUREITEM: return _HandleMeasureItem(hWnd, (MEASUREITEMSTRUCT *) lParam); case WM_DRAWITEM: return _HandleDrawItem(hWnd, (DRAWITEMSTRUCT *) lParam); case WM_INITDIALOG: CreateGlobals( hWnd ); DoAnyRandomOneTimeStuff(); g_fCleanBoot = GetSystemMetrics(SM_CLEANBOOT); TopLeftWindow( hWnd, GetParent(hWnd) ); RunOnceFill( GetDlgItem(hWnd,IDC_LIST2) ); // Now calculate the size needed for the LB and resize LB and parent. ShrinkToFit( hWnd, GetDlgItem(hWnd,IDC_LIST2)); hThread = CreateThread(NULL, 0, RunAppsInList, (LPVOID)GetDlgItem(hWnd,IDC_LIST2),0, &g_dwThread ); CloseHandle(hThread); break; case WM_FINISHED: EndDialog(hWnd,0); // DestroyWindow(hWnd); break; case WM_CTLCOLORLISTBOX: return _HandleCtlColorListbox((HWND)lParam, (HDC)uParam); case WM_COMMAND: // message: command from application menu wmId = LOWORD(uParam); wmEvent = HIWORD(uParam); if( wmEvent==LBN_SELCHANGE ) { // LaunchApp( (HWND) lParam, LOWORD(uParam) ); // De-select the item now. break; } else switch (wmId) { case IDOK: EndDialog( hWnd, wmId); break; default: // return (DefWindowProc(hWnd, message, uParam, lParam)); break; } break; default: // Passes it on if unproccessed // return (DefWindowProc(hWnd, message, uParam, lParam)); return FALSE; } return TRUE; }