//=========================================================== // WinBar - An alternative shell // // Copyright (C) 1995 Ziff-Davis Publishing Company // First published in PC Magazine by Douglas Boling // // Revision History: // // 1.0 Initial Release // //=========================================================== //----------------------------------------------------------- // Include files //----------------------------------------------------------- #include "windows.h" #include "commdlg.h" #include "shellapi.h" #include "dde.h" #include "cpl.h" #include "stdlib.h" #include "string.h" #include "dos.h" #include "direct.h" #include "time.h" #include "WinBar.h" #include "wbdll.h" #include "statbar.h" #define WM_SETHOTKEY 0x32 #define WM_GETHOTKEY 0x33 #define ODACCELMAX 1024 WNDPROC MySubClassWindow (HWND, WNDPROC); //----------------------------------------------------------- // Global data //----------------------------------------------------------- // Message dispatch table for MainWindowProc struct decodeUINT MainMessages[] = { WM_CREATE, DoCreateMain, MYMSG_CREATEBAR, DoCreateBarMain, MYMSG_LAUNCHPROG, DoLaunchProgMain, MYMSG_SHELLNOTIFY, DoShellNotifyMain, MYMSG_SHELLACTIVATE, DoShellActivateMain, MYMSG_CMDLINECMD, DoCmdLineCmdMain, WM_PAINT, DoPaintMain, WM_NCACTIVATE, DoNCActivateMain, WM_TIMER, DoTimerMain, WM_MENUCHAR, DoMenuCharMain, WM_MEASUREITEM, DoMeasureItemMain, WM_DRAWITEM, DoDrawItemMain, WM_COMMAND, DoCommandMain, WM_DDE_INITIATE, DoDDEWorkMain, WM_DDE_REQUEST, DoDDEWorkMain, WM_DDE_TERMINATE, DoDDEWorkMain, WM_QUERYENDSESSION, DoQEndSessionMain, WM_CLOSE, DoCloseMain, WM_DESTROY, DoDestroyMain, }; // Command Message dispatch for MainWindowProc struct decodeCMD MainMenuItems[] = { IDM_CONFIG, DoMainMenuConfig, IDM_EDITSTARTUP, DoMainMenuEditStartup, IDM_RUN, DoMainMenuRun, IDM_FIND, DoMainMenuFind, IDM_ABOUT, DoMainMenuAbout, IDM_EXIT, DoMainMenuExit, }; typedef LONG (CALLBACK CPIPROC) (HWND, UINT, LPARAM, LPARAM); typedef struct find_t FIND_T; typedef char huge *HPSTR; /* struct { char *szText; UINT wID; } SizeSpecs[] = {"Smaller or equal to", 1, "Larger than", 2, "Exact size", 3}; struct { char *szText; UINT wID; } DateSpecs[] = {"Before or on", 1, "Later", 2, "Exact date", 3}; */ struct { char *szName; UINT wID; } ProgMenu[] = {"Configure WinBar...", IDM_CONFIG, "About...", IDM_ABOUT}; struct { char *szName; UINT wID; } IntCmds[] = {"Show Run Dialog", IDM_RUN, // "Show Find Dialog", IDM_FIND, "Show Configure Dialog", IDM_CONFIG, "Show Edit Startup Dialog", IDM_EDITSTARTUP, "Show About Dialog", IDM_ABOUT, "Exit Program", IDM_EXIT, "No Action", -3, "Separator", -2, "Display window list", -1}; struct { char *szName; INT sMode; } DispTypes[] = {"Current Time", DISP_TIME, "Current Date", DISP_DATE, "Separator", DISP_NULL}; char szFileTag[] = "WinBar Data File 0.8 DMB 1995"; void Draw3DBorder (HDC, HPEN, HPEN, HPEN, RECT far *); INT AttachAccel (HMENU, LPSTR, INT); DWORD ProcessPick (HWND, LPSTR); LPBYTE ScanUDefMenu (HGLOBAL, UINT *, HGLOBAL *); INT ShutdownStuff (HWND); HFONT MakeFont (HDC, char *, INT, INT, INT); INT LaunchStartup (HWND, HWND, HGLOBAL); HGLOBAL RestoreMenufromMem (char huge **); HGLOBAL SavetoMem (HGLOBAL); char huge *WriteItemtoBlk (LPSTR *, HGLOBAL *, char huge **, char huge *, LONG *); INT SavetoClip (HWND, LPSTR); HGLOBAL ReadfromClip (HWND); INT FreeMenuBlk (HGLOBAL); INT GetEditFile (char *); LPSTR GetEndofName (LPSTR); HICON GetBestIcon (LPGITEMDATA, LPSTR); LPSTR IncItemPtr (LPSTR, BOOL); INT ReadfromFile (char *, HGLOBAL *, HGLOBAL *, LOGFONT *, UINT *); INT SavetoFile (HGLOBAL, HGLOBAL, HFONT, UINT, char *); INT SizeEntrySpace (LPSTR, INT, INT); char *DispHKeyText (UINT, char *, INT); void StripAmpersand (LPSTR); INT FillSubmenuBox (HWND, HGLOBAL, INT); DWORD CPLMenuOps (HGLOBAL, BOOL); DWORD WinMenuOps (HGLOBAL, UINT *); DWORD UDefMenuOps (HGLOBAL, BOOL); HGLOBAL GetGroupData (char *, char *); HGLOBAL GetGroupInfo (LPSTR, HGLOBAL *); HGLOBAL GetCPLInfo (HWND); HLOCAL GetDefaultBar (HGLOBAL *, UINT *); INT MakeStatBar (HWND, LPSTR, HFONT); INT SaveINIData (char *); INT GetINIData (char *); HANDLE hInst; HWND hMain, hLoadWnd = 0; BOOL fFirst = TRUE; UINT hTimer = 0; INT sVer = 110; char szTitleText[] = "WinBar"; // Window title text char szAppName[] = "WinBar"; // Application name char szIconName[] = "WinBarIcon"; // Icon name char szProfileName[128]; // INI file name char szLoadClass[] = "LoadWin"; // Load Window class name char szMode[] = "Mode"; char szSubMenu[] = "SubMenu"; char szChanged[] = "Changed"; ATOM aMode, aSubMenu, aChanged; WNDPROC lpfnHKeyFieldProc; HGLOBAL hCPLData = 0, hWinData = 0; HMENU hProgMenu = 0; HINSTANCE h3DLib = 0; HGLOBAL hStartup = 0; HGLOBAL hBarData = 0; LPSTR lpBar; UINT fFlags = 0; INT sCXDesk, sCYDesk; // Used for command stack char *pStack = 0; // List of owner draw menu accl keys typedef struct { HMENU hMenu; char chKey; char chPos; } ODACCEL; typedef ODACCEL *PODACCEL; PODACCEL pODAccel; INT sODAccelCnt = 0; // List of editors for bat/pif type files struct { char szExt[4]; char szCmd[128]; } BatEditors[16] = {{"BAT", "NotePad"}, {"PIF", "PIFEdit"}}; INT sBatEdCnt = 2; // List of icon library files struct { char szName[128]; } IconLibs[16] = {"progman.exe", "moricons.dll"}; INT sIconLibCnt = 2; // Vars for DDE com with WinOldApp. char *pLaunch = 0; HINSTANCE hLastLaunch; // Vars for clipboard support char szMyClipFormat[] = "WinBarItemFormat"; UINT hWBClipFmt = 0; char szDebug[256]; //============================================================ // WinMain -- entry point for this application from Windows. //============================================================ INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) { MSG msg; INT rc; HWND hLast; hInst = hInstance; // Don't allow more than one instance. if (hPrevInstance) { hLast = FindWindow (szAppName, NULL); if (hLast) { SendMessage (hLast, MYMSG_CMDLINECMD, 0, (LPARAM)lpCmdLine); return 0; } return 1; } // Init first instance of program. rc = InitApp(hInstance); if (rc) return rc; // Initialize this instance if((rc = InitInstance(hInstance, lpCmdLine, nCmdShow)) != 0) return rc; // Application message loop while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // Instance cleanup return TermInstance(hInstance, msg.wParam); } //----------------------------------------------------------- // InitApp - Global initialization code for this application. //----------------------------------------------------------- INT InitApp(HANDLE hInstance) { WNDCLASS wc; // // Register App Main Window class // wc.style = 0; // Window style wc.lpfnWndProc = MainWndProc; // Callback function wc.cbClsExtra = 0; // Extra class data wc.cbWndExtra = sizeof (HGLOBAL); // Extra window data wc.hInstance = hInstance; // Owner handle wc.hIcon = LoadIcon(hInst, szIconName); // Application icon wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default cursor wc.hbrBackground = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)); wc.lpszMenuName = NULL; // Menu name wc.lpszClassName = szAppName; // Window class name if (RegisterClass(&wc) == 0) return 1; // Register loading... window class wc.style = 0; // Window style wc.lpfnWndProc = LoadWndProc; // Callback function wc.cbClsExtra = 0; // Extra class data wc.cbWndExtra = 0; // Extra window data wc.hInstance = hInstance; // Owner handle wc.hIcon = LoadIcon(hInst, szIconName); // Application icon wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default cursor wc.hbrBackground = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)); wc.lpszMenuName = NULL; // Menu name wc.lpszClassName = szLoadClass; // Window class name if (RegisterClass(&wc) == 0) return 1; // Register custom clipboard format hWBClipFmt = RegisterClipboardFormat (szMyClipFormat); // Init status bar window class StatusBarInit (hInstance); return 0; } //----------------------------------------------------------- // InitInstance - Instance initialization code for this app. //----------------------------------------------------------- INT InitInstance(HANDLE hInstance, LPSTR lpCmdLine, INT nCmdShow) { INT i, x, y, cx, cy; BOOL fShell = FALSE; HGLOBAL hNewBarData; RECT rect; char szTemp[128]; LOGFONT fm; UINT wHotKey = 0; HFONT hFont = 0; OFSTRUCT of; HCURSOR hOld; // Get program name. Used to get INI name and the shell test i = GetModuleFileName (hInstance, szProfileName, sizeof (szProfileName)); // See if we are the windows shell GetPrivateProfileString ("boot", "shell", "noway", szTemp, sizeof (szTemp), "SYSTEM.INI"); OpenFile (szTemp, &of, OF_PARSE); if (lstrcmpi (of.szPathName, szProfileName) == 0) fShell = TRUE; // Convert program name to INI file name while (szProfileName[i--] != '.'); lstrcpy (&szProfileName[i+2], "INI"); GetINIData (szProfileName); // Create atoms necessary for win props aSubMenu = GlobalAddAtom (szSubMenu); aMode = GlobalAddAtom (szMode); aChanged = GlobalAddAtom (szChanged); // Create proc instance for hotkey entry field subclass proc lpfnHKeyFieldProc = (WNDPROC)MakeProcInstance ((FARPROC) HKeyFieldProc, hInst); // If 3DLib present, load it for 3d effects. h3DLib = LoadLibrary ("CTL3D.DLL"); if (h3DLib < HINSTANCE_ERROR) h3DLib = 0; hOld = SetCursor (LoadCursor (NULL, IDC_WAIT)); // Create 'Loading...' Window hLoadWnd = CreateWindowEx (WS_EX_TOPMOST, szLoadClass, "Loading...", WS_POPUP, 0, 0, 300, 225, HWND_DESKTOP, NULL, hInstance, 0); MyYield(); InvalidateRect (hLoadWnd, NULL, FALSE); // // Create main window // GetClientRect (GetDesktopWindow(), &rect); cx = rect.right - rect.left; cy = 5; x = rect.left; y = rect.bottom - cy; hMain = CreateWindowEx (WS_EX_TOPMOST, szAppName, szTitleText, WS_POPUP | WS_BORDER, x, y, cx, cy, HWND_DESKTOP, NULL, hInstance, 0); if(!hMain) return 0x10; MyYield(); //Get config info // hCPLData = GetCPLInfo(hMain); hWinData = GlobalAlloc (GHND, 0x1000); if (hWinData == 0) return 0x21; GlobalLock (hWinData); // Alloc mem for cmd stack pStack = (char *)LocalAlloc (LPTR, CMDSTACKSIZE); if (pStack == 0) return 0x22; // Alloc mem for owner drawn access keys pODAccel = (PODACCEL)LocalAlloc (LPTR, ODACCELMAX * sizeof (ODACCEL)); if (pODAccel == 0) return 0x23; // Call down to DLL SetStatus (hMain, DFLAG_UNHOOK, 0); // Load bar config data from file or create new data i = GetModuleFileName (hInstance, szTemp, sizeof (szTemp)); lstrcpy (&szTemp[i-3], "DAT"); x = ReadfromFile(szTemp, &hNewBarData, &hStartup, &fm, &wHotKey); if (x == 0) { hFont = CreateFontIndirect (&fm); if (wHotKey) PostMessage (hMain, WM_SETHOTKEY, wHotKey, 0); } else { if (x != ERR_DOSFILENOFND) PrintError (hMain, x); hCPLData = GetCPLInfo(hMain); hNewBarData = GetDefaultBar (&hStartup, &fFlags); } if (hNewBarData == 0) return 0x20; SendMessage (hMain, MYMSG_CREATEBAR, hFont, MAKELONG (hNewBarData, 1)); //If shell, launch the progs if (fShell) { fFlags |= FLAG_SHELL; LaunchStartup (hMain, hLoadWnd, hStartup); MyYield(); MyArrangeIcons (); } else fFlags &= ~FLAG_SHELL; hTimer = SetTimer (hMain, 1, 1000, NULL); ShowWindow(hMain, SW_SHOW); UpdateWindow(hMain); // force WM_PAINT message // Nuke 'loading...' window DestroyWindow (hLoadWnd); hLoadWnd = 0; SetCursor (hOld); return 0; // return success flag } //------------------------------------------------------------ // TermInstance - Instance termination code for this app. //------------------------------------------------------------ INT TermInstance(HANDLE hInstance, int sDefRC) { // Save profile data SaveINIData (szProfileName); // Delete atoms necessary for win props GlobalDeleteAtom (aSubMenu); GlobalDeleteAtom (aMode); GlobalDeleteAtom (aChanged); StatusBarTerm (hInstance); FreeProcInstance ((FARPROC) lpfnHKeyFieldProc); if (h3DLib) FreeLibrary (h3DLib); if (pStack) LocalFree ((HLOCAL)pStack); if (hBarData) { GlobalUnlock (hBarData); FreeMenuBlk (hBarData); } if (hCPLData) { GlobalUnlock (hCPLData); GlobalFree (hCPLData); } if (hWinData) { GlobalUnlock (hWinData); GlobalFree (hWinData); } return sDefRC; } //------------------------------------------------------------ // ParseINIString - Parses file names from an ini string //------------------------------------------------------------ char *ParseINIString (char *pszIn, LPSTR pszOut, LPSTR pszName) { LPSTR lpStart; lpStart = pszName; if (*pszIn) { // Find first char of name while ((*pszIn) && (*pszIn <= ' ')) pszIn++; // Copy name while (*pszIn > ' ') { *pszName++ = *pszIn; if (*pszIn == '\\') pszName = lpStart; *pszOut++ = *pszIn++; } *pszOut = '\0'; *pszName = '\0'; } return pszIn; } //------------------------------------------------------------ // LaunchStartup - Launches startup programs if we are shell //------------------------------------------------------------ INT LaunchStartup (HWND hWnd, HWND hLoad, HGLOBAL hStartup) { char szTemp[256]; char szStat[128]; char *pszTemp; char szProg[sizeof (GITEMDATA) + 1]; LPGITEMDATA lpProg; LPSTR lpPtr; INT i, sCnt; memset (szProg, 0, sizeof (GITEMDATA)+1); lpProg = (LPGITEMDATA)((LPSTR)szProg+1); lpProg->sType = MTYPE_PROG; // Get and parse load line GetPrivateProfileString ("windows", "load", "", szTemp, sizeof (szTemp), "WIN.INI"); pszTemp = szTemp; lpProg->wStartFlags = SW_SHOWMINIMIZED; lstrcpy (szStat, "Loading "); while (*pszTemp) { pszTemp = ParseINIString (pszTemp, lpProg->szCmd, &szStat[8]); SetWindowText (hLoad, szStat); SendMessage (hWnd, MYMSG_LAUNCHPROG, 0, (LPARAM)(LPSTR)szProg); } // Get and parse run line GetPrivateProfileString ("windows", "run", "", szTemp, sizeof (szTemp), "WIN.INI"); pszTemp = szTemp; lpProg->wStartFlags = SW_SHOW; lstrcpy (szStat, "Running "); while (*pszTemp) { pszTemp = ParseINIString (pszTemp, lpProg->szCmd, &szStat[8]); SetWindowText (hLoad, szStat); SendMessage (hWnd, MYMSG_LAUNCHPROG, 0, (LPARAM)(LPSTR)szProg); } // Launch startup group programs if not shift if (!(GetKeyState (VK_SHIFT) & 0x8000)) { lpPtr = GlobalLock (hStartup); if (lpPtr) { sCnt = *((LPWORD)lpPtr)++; for (i = 0; i < sCnt; i++) { lstrcpy (szStat, " Launching "); lstrcat (szStat, lpPtr); SetWindowText (hLoad, szStat); SendMessage (hWnd, MYMSG_LAUNCHPROG, 0, (LPARAM)lpPtr); lpPtr = IncItemPtr (lpPtr, TRUE); } GlobalUnlock (hStartup); } } return 0; } //============================================================ // Message handling procedures for MainWindow //============================================================ //------------------------------------------------------------ // MainWndProc - Callback function for application window //------------------------------------------------------------ LONG CALLBACK MainWndProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { INT i; // // Search message list to see if we need to handle this // message. If in list, call procedure. // for(i = 0; i < dim(MainMessages); i++) { if(wMsg == MainMessages[i].Code) return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam); } return DefWindowProc(hWnd, wMsg, wParam, lParam); } //------------------------------------------------------------ // DoCreateMain - process WM_CREATE message for frame window. //------------------------------------------------------------ LONG DoCreateMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { FARPROC lp3dproc; if (h3DLib) { lp3dproc = GetProcAddress (h3DLib, "Ctl3dRegister"); if (lp3dproc) { (*lp3dproc) (hInst); lp3dproc = GetProcAddress (h3DLib, "Ctl3dAutoSubclass"); if (lp3dproc) { (*lp3dproc) (hInst); } } else { FreeLibrary (h3DLib); h3DLib = 0; } } return 0; } //------------------------------------------------------------ // DoCreateBarMain - process MYMSG_CREATEBAR message for frame window. //------------------------------------------------------------ LONG DoCreateBarMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { HWND hwndStatBar; HDC hdc; INT x, y, cx, cy; RECT rect; HFONT hFont = 0; TEXTMETRIC tm; HGLOBAL hNewBar, hOldBar = 0; LPSTR lpNewBar; LONG lStyle; hwndStatBar = GetDlgItem (hWnd, IDD_STATBAR); if (hwndStatBar) DestroyWindow (hwndStatBar); // If font specified, delete old one hdc = GetDC(NULL); if (wParam) hFont = (HFONT) wParam; else hFont = MakeFont (hdc, "Helv", 8, FW_BOLD, 0); // If bar structure specified, delete old one if (lParam) { hNewBar = (HGLOBAL)LOWORD (lParam); if (!hNewBar) return ERR_BADBARSEG; if (hNewBar != hBarData) { lpNewBar = GlobalLock (hNewBar); if (!lpNewBar) return ERR_BADBARSEG; hOldBar = hBarData; } else lpNewBar = lpBar; } else lpNewBar = lpBar; // Get font stats to determine size of things x = SelectObject (hdc, hFont); GetTextMetrics(hdc, &tm); SelectObject (hdc, x); ReleaseDC(NULL, hdc); // Recompute the size and position of the main window GetWindowRect (hWnd, &rect); cx = GetSystemMetrics (SM_CXSCREEN); cy = tm.tmHeight + tm.tmExternalLeading + 10 + 4; x = 0; y = GetSystemMetrics (SM_CYSCREEN) - cy; SetWindowPos (hWnd, NULL, x, y, cx, cy, SWP_NOZORDER | SWP_FRAMECHANGED); // Set topmost window style if necessary. lStyle = GetWindowLong (hWnd, GWL_EXSTYLE); if (fFlags & FLAG_ALWAYSONTOP) { if (!(lStyle & WS_EX_TOPMOST)) SetWindowPos (hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); } else { if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); } // Make the status bar x = MakeStatBar (hWnd, lpNewBar, hFont); if (x == 0) { // Tell the icon DLL our new height if (fFlags & FLAG_ALWAYSONTOP) SetStatus (hMain, DFLAG_HOOK, cy); else SetStatus (hMain, DFLAG_HOOK | DFLAG_HIDEBAR, cy); MyArrangeIcons(); if (hOldBar) { GlobalUnlock (hOldBar); lpBar = 0; FreeMenuBlk (hOldBar); } lpBar = lpNewBar; hBarData = hNewBar; // Have the frame redrawn SendMessage (hWnd, WM_NCACTIVATE, TRUE, 0); // Send timer messgage to force a time and date update SendMessage (hWnd, WM_TIMER, 1, 0); } else { // Clean up new stuff GlobalUnlock (hBarData); DeleteObject (hFont); x -= ERR_STATBAR; } return x; } //------------------------------------------------------------ // DoLaunchProgMain - process MYMSG_LAUNCHPROG message //------------------------------------------------------------ LONG DoLaunchProgMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { HINSTANCE hExecInst; LPSTR lpPtr; LPGITEMDATA lpProg; LPSTR lpEnd, lpTemp; char szTemp[129]; HCURSOR hOld; if (lParam == 0) return 0; lpPtr = (LPSTR) lParam; lpProg = (LPGITEMDATA)(lpPtr + lstrlen (lpPtr) + 1); if (lpProg->sType == MTYPE_BARITEM) lpProg = (LPGITEMDATA)((LPSTR)lpProg + sizeof (BARITEMDATA)); if (lpProg->sType != MTYPE_PROG) return 0; if (lstrlen (lpProg->szDir) != 0) { if (lpProg->szDir[1] == ':') { //UCase drive letter & convert to num. _chdrive ((lpProg->szDir[0] & 0xdf) - 0x40); } lstrcpy (szTemp, lpProg->szDir); chdir (szTemp); } lstrcpy (szTemp, lpProg->szCmd); // Find end of file name lpEnd = GetEndofName (szTemp); // Slide params over one char to insert zero byte lpTemp = szTemp + lstrlen (szTemp); if (lpTemp > lpEnd) { while (lpTemp >= lpEnd) { *(lpTemp+1) = *lpTemp; lpTemp--; } lpTemp++; *lpTemp++ = '\0'; } hOld = SetCursor (LoadCursor (NULL, IDC_WAIT)); hExecInst = ShellExecute (hMain, NULL, szTemp, lpTemp, lpProg->szDir, lpProg->wStartFlags); SetCursor (hOld); // If good launch, save data for DDE query if (hExecInst < 32) { PrintError (hMain, ERR_LAUNCH + hExecInst); } else { if (pLaunch == 0) pLaunch = (char *)LocalAlloc (LPTR, 128 + sizeof (GITEMDATA)); if (pLaunch) { _fmemmove (pLaunch, lpPtr, (LPSTR)lpProg + sizeof (GITEMDATA) - lpPtr); hLastLaunch = hExecInst; } } return 0; } //------------------------------------------------------------ // DoCmdLineCmdMain - process MYMSG_CMDLINECMD message for frame window. //------------------------------------------------------------ LONG DoCmdLineCmdMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { LPSTR lpCmd; UINT vKey; if (!lParam) return 0; // Activate us SetActiveWindow (hWnd); lpCmd = (LPSTR) lParam; // If leading ampersand, must be a hotkey if (*lpCmd == '&') { vKey = VkKeyScan (*(lpCmd+1)); vKey &= 0x00ff; PostMessage (hWnd, WM_SYSKEYDOWN, vKey, 0x20000000); } return 0; } //------------------------------------------------------------ // DoNCActivateMain - process WM_NCACTIVATE message for frame window. //------------------------------------------------------------ LONG DoNCActivateMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { RECT rect; GetClientRect (hWnd, &rect); rect.bottom = rect.top + 2; InvalidateRect (hWnd, &rect, FALSE); return DefWindowProc(hWnd, wMsg, wParam, lParam); } //------------------------------------------------------------ // DoPaintMain - process WM_PAINT message for frame window. //------------------------------------------------------------ LONG DoPaintMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { PAINTSTRUCT ps; BOOL fFocus = FALSE; HWND hwndFocus; HDC hdc; LONG rc; RECT rect; HPEN hOldPen, hPenT, hPenB; hdc = BeginPaint (hWnd, &ps); hwndFocus = GetFocus (); if (IsWindow(hwndFocus)) if (GetWindowWord (hwndFocus, GWW_HINSTANCE) == hInst) fFocus = TRUE; if (fFocus) { hPenT = CreatePen (PS_SOLID, 4, GetSysColor (COLOR_ACTIVECAPTION)); hPenB = CreatePen (PS_SOLID, 2, GetSysColor (COLOR_ACTIVEBORDER)); } else { hPenT = CreatePen (PS_SOLID, 4, GetSysColor (COLOR_INACTIVECAPTION)); hPenB = CreatePen (PS_SOLID, 2, GetSysColor (COLOR_INACTIVEBORDER)); } GetClientRect (hWnd, &rect); hOldPen = SelectObject (hdc, hPenT); MoveTo (hdc, rect.left, rect.top+2); LineTo (hdc, rect.right, rect.top+2); SelectObject (hdc, hOldPen); DeleteObject (hPenT); DeleteObject (hPenB); EndPaint (hWnd, &ps); return rc; } //------------------------------------------------------------ // DoTimerMain - process WM_TIMER message for frame window. //------------------------------------------------------------ LONG DoTimerMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { char szTime[64], szDate[64]; char *pszTime; LPSTR lpPtr; LONG lTime; INT i; struct tm *now; static char *pszDays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; static char *pszMonths[12] = {"Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."}; if (hTimer == 0) return 0; if (lpBar == 0) return 0; if (!GlobalSize (hBarData)) return 0; // Generate time and date strings time (&lTime); pszTime = ctime (&lTime); now = localtime (&lTime); if (now == 0) return 0; // Create date string lstrcpy (szDate, pszDays[now->tm_wday]); lstrcat (szDate, " "); lstrcat (szDate, pszMonths[now->tm_mon]); wsprintf (&szDate[lstrlen (szDate)], " %d, %d",now->tm_mday, now->tm_year+1900); // Create time string if (now->tm_hour < 12) { if (now->tm_hour == 0) now->tm_hour = 12; wsprintf (szTime, "%d:%02d AM",now->tm_hour, now->tm_min); } else { if (now->tm_hour > 12) now->tm_hour -= 12; wsprintf (szTime, "%d:%02d PM",now->tm_hour, now->tm_min); } // Scan bar to see if time and date fields exist lpPtr = lpBar; lpPtr += sizeof (INT); for (i = 0; i < *(LPINT)lpBar; i++) { lpPtr += lstrlen (lpPtr) + 1; if (((LPBARITEMDATA)lpPtr)->sDisplayMode == DISP_TIME) SetStatusBarText (hWnd, szTime, i); else if (((LPBARITEMDATA)lpPtr)->sDisplayMode == DISP_DATE) SetStatusBarText (hWnd, szDate, i); lpPtr = IncItemPtr (lpPtr, FALSE); } return 0; } //------------------------------------------------------------ // DoShellActivateMain - process MYMSG_SHELLACTIVATE message // This message is sent from the companion DLL WBDLL when // it detects one of the MS keyboard's special keys. //------------------------------------------------------------ LONG DoShellActivateMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { //OutputDebugString ("MYMSG_SHELLACTIATE Message received\n"); SetFocus (hWnd); return 0; } //------------------------------------------------------------ // DoShellNotifyMain - process MYMSG_SHELLNOTIFY message // This message is sent from the companion DLL WBDLL when it's // shell hook receives these messages. //------------------------------------------------------------ LONG DoShellNotifyMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { HWND hwndLaunched; HINSTANCE hInstLaunched; GITEMDATA *pProg; WINDOWPLACEMENT wp; LONG lStyle; switch (wParam) { case HSHELL_ACTIVATESHELLWINDOW: //OutputDebugString ("Activate Shell Message received\n"); //MessageBeep(0); break; case HSHELL_WINDOWCREATED: hwndLaunched = (HWND) lParam; if (IsWindow (hwndLaunched)) { hInstLaunched = GetWindowWord (hwndLaunched, GWW_HINSTANCE); // If we launched this app, set hotkey if necessary if (hInstLaunched == hLastLaunch) { // get ptr to last launched structure pProg = (GITEMDATA *)(pLaunch + lstrlen (pLaunch) + 1); if (pProg->wHotKey) SendMessage (hwndLaunched, WM_SETHOTKEY, pProg->wHotKey, 0); } // Now reset the icon position values. lStyle = GetWindowLong (hwndLaunched, GWL_STYLE); if ((lStyle & WS_VISIBLE) && !(lStyle & WS_CHILD)) { wp.length = sizeof (wp); GetWindowPlacement (hwndLaunched, &wp); if ((wp.showCmd == SW_MINIMIZE) || (wp.showCmd == SW_SHOWMINNOACTIVE) || (wp.showCmd == SW_SHOWMINIMIZED)) { //Set new icon position ComputeNextIPos (hwndLaunched, &wp.ptMinPosition); } else { wp.ptMinPosition.x = -2; wp.ptMinPosition.y = -2; wp.flags |= WPF_SETMINPOSITION; SetWindowPlacement (hwndLaunched, &wp); } } } break; case HSHELL_WINDOWDESTROYED: break; } return 0; } //------------------------------------------------------------ // DoDDEWorkMain - process WM_DDE_xxx messages //------------------------------------------------------------ LONG DoDDEWorkMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { char szAtomName[80]; HWND hWndOldApp; HINSTANCE hExecInst; LPSTR lpData, lpIcon; GITEMDATA *pProg; HGLOBAL hData; HICON hIcon; UINT wOffset; INT wSize, rc; hWndOldApp = (HWND)wParam; switch (wMsg) { case WM_DDE_INITIATE: // See if addressing the Shell GlobalGetAtomName (LOWORD (lParam), szAtomName, sizeof (szAtomName)); if (lstrcmpi (szAtomName, "Shell") == 0) { // See if App properties topic GlobalGetAtomName (HIWORD (lParam), szAtomName, sizeof (szAtomName)); if (lstrcmpi (szAtomName, "AppProperties") == 0) SendMessage ((HWND) wParam, WM_DDE_ACK, hWnd, lParam); } return 0; case WM_DDE_REQUEST: rc = 0; hExecInst = LOWORD (lParam); // See if reqesting info on last launched app if (hExecInst == hLastLaunch) { // Create ptr to prog info structure for last launched app if (pLaunch == 0) rc = 1; // Allocate mem for DDE data hData = GlobalAlloc (GMEM_DDESHARE | GHND, 0x10000); if (hData) lpData = GlobalLock (hData); else rc = 2; if (rc) { // Post a negitive ack msg PostMessage ((HWND) wParam, WM_DDE_ACK, hWnd, MAKELPARAM (0, HIWORD (lParam))); return 0; } // Init DDEDATA structure ((DDEDATA far *)lpData)->fRelease = 1; ((DDEDATA far *)lpData)->cfFormat = CF_TEXT; // See what information being requested GlobalGetAtomName (HIWORD (lParam), szAtomName, sizeof (szAtomName)); if (lstrcmpi (szAtomName, "GetDescription") == 0) { // Copy prog description string lstrcpy (((DDEDATA far *)lpData)->Value, pLaunch); // strip off and ampersand in description StripAmpersand (((DDEDATA far *)lpData)->Value); } else if (lstrcmpi (szAtomName, "GetWorkingDIR") == 0) { // Move past prog description string pProg = (GITEMDATA *)(pLaunch + lstrlen (pLaunch) + 1); // Copy working directory string lstrcpy (((DDEDATA far *)lpData)->Value, pProg->szDir); } else if (lstrcmpi (szAtomName, "GetIcon") == 0) { rc = 0; pProg = (GITEMDATA *)(pLaunch + lstrlen (pLaunch) + 1); hIcon = GetBestIcon ((LPGITEMDATA)pProg, 0); if (hIcon > 1) { lpIcon = GlobalLock ((HGLOBAL)hIcon); if (lpIcon) { ((LPICONPROPS)lpData)->cfFormat = 0; ((LPICONPROPS)lpData)->nWidth = *(LPWORD)(lpIcon+4); ((LPICONPROPS)lpData)->nHeight = *(LPWORD)(lpIcon+6); ((LPICONPROPS)lpData)->nPlanes = *(lpIcon+0xa); ((LPICONPROPS)lpData)->nBitsPixel = *(lpIcon+0xb); wOffset = OFFSETOF (lpData) + sizeof (ICONPROPS); wSize = (((LPICONPROPS)lpData)->nWidth * ((LPICONPROPS)lpData)->nHeight) / 8; lpIcon += 0x0c; ((LPICONPROPS)lpData)->lpANDbits = MAKELP (0, wOffset); _fmemmove (lpData + wOffset, lpIcon, wSize); wOffset += wSize; lpIcon += wSize; wSize = (((LPICONPROPS)lpData)->nWidth * ((LPICONPROPS)lpData)->nHeight * ((LPICONPROPS)lpData)->nBitsPixel) / 8; ((LPICONPROPS)lpData)->lpXORbits = MAKELP (0, wOffset); _fmemmove (lpData + wOffset, lpIcon, wSize); GlobalUnlock ((HGLOBAL)hIcon); } else rc = 1; DestroyIcon (hIcon); } else rc = 1; if (rc) { GlobalUnlock (hData); GlobalFree (hData); // Post a negitive ack msg PostMessage ((HWND) wParam, WM_DDE_ACK, hWnd, MAKELPARAM (0, HIWORD (lParam))); return 0; } } else { GlobalUnlock (hData); GlobalFree (hData); // Post a negitive ack msg PostMessage ((HWND) wParam, WM_DDE_ACK, hWnd, MAKELPARAM (0, HIWORD (lParam))); return 0; } GlobalUnlock (hData); // Respond to the message PostMessage ((HWND) wParam, WM_DDE_DATA, hWnd, MAKELPARAM (hData, HIWORD (lParam))); } break; case WM_DDE_TERMINATE: break; } return 0; } //------------------------------------------------------------ // DoDrawItemMain - process WM_DRAWITEM message for Main window. //------------------------------------------------------------ LONG DoDrawItemMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { LPDRAWITEMSTRUCT di; HDC hdc; HFONT hOldFont, hFont; RECT rect; LPSTR lpszText; HPEN hLPen, hDPen, hOldPen, hNPen; HBRUSH hBr; di = (LPDRAWITEMSTRUCT) lParam; if (!di) return 0; hdc = di->hDC; hFont = (HFONT)SendDlgItemMessage (hWnd, IDD_STATBAR, WM_GETFONT, 0, 0); if (!hFont) hFont = GetStockObject (SYSTEM_FONT); hOldFont = SelectObject (hdc, hFont); if ((di->itemState == ODS_GRAYED) || (di->itemState == ODS_GRAYED)) SetTextColor (hdc, GetSysColor (COLOR_GRAYTEXT)); else SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT)); SetBkColor (hdc, GetSysColor (COLOR_BTNFACE)); hNPen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNFACE)); hDPen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNSHADOW)); hLPen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNHIGHLIGHT)); rect = di->rcItem; hBr = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)); FillRect (hdc, &rect, hBr); DeleteObject (hBr); rect.top += 2; rect.bottom -= 2; rect.left += 5; rect.right -= 5; lpszText = (LPSTR) di->itemData; if (((INT)di->itemID > 0) || (IsMenu (di->itemID))) { DrawText (hdc, lpszText, -1, &rect, DT_VCENTER | DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS); rect = di->rcItem; rect.left -= 1; rect.right += 1; switch (di->itemAction) { case ODA_FOCUS: if (di->itemState & ODS_FOCUS) { Draw3DRect (hdc, hDPen, hLPen, &rect, FLAG_DIN2); Draw3DBorder (hdc, hNPen, hNPen, hNPen, &rect); } else { Draw3DRect (hdc, hNPen, hNPen, &rect, FLAG_DIN2); Draw3DBorder (hdc, hDPen, hNPen, hLPen, &rect); } break; case ODA_DRAWENTIRE: Draw3DBorder (hdc, hDPen, hNPen, hLPen, &rect); break; case ODA_SELECT: if (di->itemState & ODS_SELECTED) { Draw3DRect (hdc, hDPen, hLPen, &rect, FLAG_DIN2); Draw3DBorder (hdc, hNPen, hNPen, hNPen, &rect); } else { Draw3DRect (hdc, hNPen, hNPen, &rect, FLAG_DIN2); Draw3DBorder (hdc, hDPen, hNPen, hLPen, &rect); } break; } } else { rect = di->rcItem; rect.left -= 1; rect.right += 1; Draw3DBorder (hdc, hDPen, hNPen, hLPen, &rect); // Draw sep if ((INT)di->itemID == -4) { hOldPen = SelectObject (hdc, hDPen); MoveTo (hdc, rect.left, rect.top+2); LineTo (hdc, rect.right, rect.top+2); SelectObject (hdc, hLPen); MoveTo (hdc, rect.left, rect.top+3); LineTo (hdc, rect.right, rect.top+3); // Draw top of menu } else if ((INT)di->itemID == -2) { hOldPen = SelectObject (hdc, hLPen); MoveTo (hdc, rect.left, rect.top-0); LineTo (hdc, rect.right, rect.top-0); MoveTo (hdc, rect.left+1, rect.top+1); LineTo (hdc, rect.right-1, rect.top+1); // Draw bottom of menu } else { rect.bottom += 1; hOldPen = SelectObject (hdc, hDPen); MoveTo (hdc, rect.left, rect.bottom+0); LineTo (hdc, rect.right, rect.bottom+0); MoveTo (hdc, rect.left+1, rect.bottom-1); LineTo (hdc, rect.right-1, rect.bottom-1); } SelectObject (hdc, hOldPen); } DeleteObject (hDPen); DeleteObject (hLPen); DeleteObject (hNPen); SelectObject (hdc, hOldFont); return TRUE; } //------------------------------------------------------------ // DoMeasureItemMain - process WM_MEASUREITEM message for Main window. //------------------------------------------------------------ LONG DoMeasureItemMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { LPMEASUREITEMSTRUCT mi; HDC hdc; HFONT hOldFont, hFont; LPSTR lpszText; mi = (LPMEASUREITEMSTRUCT) lParam; if (!mi) return 0; mi->itemHeight = ComputeItemHeight (GetDlgItem (hWnd, IDD_STATBAR), (INT)mi->itemID); if (((INT)mi->itemID > 0) || (IsMenu (mi->itemID))) { hdc = GetDC (hWnd); hFont = (HFONT)SendDlgItemMessage (hWnd, IDD_STATBAR, WM_GETFONT, 0, 0); hOldFont = SelectObject (hdc, hFont); lpszText = (LPSTR)mi->itemData; if (lpszText) mi->itemWidth = LOWORD (GetTextExtent (hdc, lpszText, lstrlen (lpszText))); else mi->itemWidth = 20; SelectObject (hdc, hOldFont); ReleaseDC (hWnd, hdc); } else { mi->itemWidth = 20; } return TRUE; } //------------------------------------------------------------ // DoMenuCharMain - process WM_MENUCHAR message for status bar //------------------------------------------------------------ LONG DoMenuCharMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { INT i; HMENU hMenu; PODACCEL pAccel; char ch; ch = (BYTE)(DWORD)AnsiUpper ((LPSTR)(DWORD)wParam); hMenu = (HMENU)HIWORD(lParam); // See if char in list pAccel = pODAccel; for (i = 0; i < sODAccelCnt; i++) { if ((pAccel->hMenu == hMenu) && (pAccel->chKey == ch)) return MAKELONG ((UINT)pAccel->chPos, 2); pAccel++; } return 0; } //------------------------------------------------------------ // DoCommandMain - process WM_COMMAND message for frame window // by decoding the menubar item with the menuitems[] array, // then running the corresponding function to process the command. //------------------------------------------------------------ LONG DoCommandMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { UINT idItem, wNotifyCode, wID = 1; HGLOBAL hGlobal; LPSTR lpPtr; INT i; HWND hwndCtl; LONG lData; idItem = (UINT) wParam; // Parse Parameters hwndCtl = (HWND) LOWORD(lParam); wNotifyCode = (UINT) HIWORD(lParam); if (hwndCtl == GetDlgItem (hWnd, IDD_STATBAR)) { lData = SendDlgItemMessage (hWnd, IDD_STATBAR, STATM_GETITEMDATA, idItem, 0); switch (wNotifyCode) { case STATN_CREATEMENU: switch (HIWORD (lData)) { case MENU_USERDEF: // Clear accel tables AttachAccel (0, 0, 0); return MAKELONG (UDefMenuOps (LOWORD (lData), TRUE), HIWORD (lData)); case MENU_WINDOWS: return WinMenuOps (hWinData, &wID); } return 0; case STATN_DESTROYMENU: switch (HIWORD (lData)) { case MENU_USERDEF: return UDefMenuOps (LOWORD (lData), FALSE); case MENU_WINDOWS: GlobalUnlock (LOWORD (lData)); return 0; } break; case STATN_CLICKED: ProcessPick (hWnd, (LPSTR)lData); break; case STATN_PICKMENU: idItem = (UINT) SendDlgItemMessage (hWnd, IDD_STATBAR, STATM_GETEVENTDATA, 0, 0); lpPtr = ScanUDefMenu (LOWORD(lData), &idItem, &hGlobal); ProcessPick (hWnd, lpPtr); break; } } else { // // Call routine to handle control message // for(i = 0; i < dim(MainMenuItems); i++) { if(idItem == MainMenuItems[i].Code) return (*MainMenuItems[i].Fxn)(hWnd, idItem, hwndCtl, wNotifyCode); } } return 0; } //------------------------------------------------------------ // DoQEndSessionMain - process WM_QUERYENDSESSION message for frame // window. //------------------------------------------------------------ LONG DoQEndSessionMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { if (!(fFlags & FLAG_SHELL)) { if (ShutdownStuff (hWnd) == 0) return 0; } return 1; } //------------------------------------------------------------ // DoCloseMain - process WM_CLOSE message for frame window. //------------------------------------------------------------ LONG DoCloseMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { if (fFlags & FLAG_SHUTDOWN) return DefWindowProc(hWnd, wMsg, wParam, lParam); if (ShutdownStuff (hWnd) == 0) return 0; return DefWindowProc(hWnd, wMsg, wParam, lParam); } //------------------------------------------------------------ // DoDestroyMain - process WM_DESTROY message for frame window. //------------------------------------------------------------ LONG DoDestroyMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { FARPROC lp3dproc; if (h3DLib) { lp3dproc = GetProcAddress (h3DLib, "Ctl3dUnregister"); if (lp3dproc) (*lp3dproc) (hInst); } if (hTimer) { KillTimer (hWnd, 1); hTimer = 0; } PostQuitMessage (0); return DefWindowProc(hWnd, wMsg, wParam, lParam); } //============================================================ // Control handling procedures for MainWindow //============================================================ //------------------------------------------------------------ // DoMainMenuConfig - Process Config menu item //------------------------------------------------------------ LONG DoMainMenuConfig (HWND hWnd, UINT idItem, HWND hwndCtl, UINT wNotifyCode) { LONG lStyle; RECT rect; // Un-topmost window so Dlg won't be topmost lStyle = GetWindowLong (hWnd, GWL_EXSTYLE); if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); // Kill timer so we don't get updates while editing bar KillTimer (hWnd, 1); hTimer = 0; MyDisplayDialog(hInst, "ConfigBox", hWnd, (DLGPROC)ConfigDlgProc, 0); hTimer = SetTimer (hMain, 1, 1000, NULL); // Set topmost window style if necessary. if (fFlags & FLAG_ALWAYSONTOP) SetWindowPos (hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); // Tell DLL how to handle maximized windows GetWindowRect (hWnd, &rect); if (fFlags & FLAG_ALWAYSONTOP) SetStatus (hMain, DFLAG_HOOK, rect.bottom - rect.top); else SetStatus (hMain, DFLAG_HOOK | DFLAG_HIDEBAR, rect.bottom - rect.top); return 0; } //------------------------------------------------------------ // DoMainMenuEditStartup - Process Edit Startup menu item //------------------------------------------------------------ LONG DoMainMenuEditStartup (HWND hWnd, UINT idItem, HWND hwndCtl, UINT wNotifyCode) { char szBuff[10]; char *pPtr; EDITITEM ei; LONG lStyle; HGLOBAL hEdit; LPSTR lpPtr; // Un-topmost window so Dlg won't be topmost lStyle = GetWindowLong (hWnd, GWL_EXSTYLE); if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); // Create fake submenu structure. pPtr = szBuff; *pPtr++ = '\0'; *((INT *)pPtr)++ = MTYPE_SUBMENU; *((INT *)pPtr)++ = hStartup; ei.sMode = 1; ei.lParam = (LPARAM)(LPSTR)szBuff; // Edit startup using startup dlg template and edit item proc hEdit = MyDisplayDialog(hInst, "EditStartup", hWnd, (DLGPROC)EditItemDlgProc, (LPARAM)(LPEDITITEM)&ei); //zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz if (hEdit) { lpPtr = GlobalLock (hEdit); if (lpPtr) { lpPtr += lstrlen (lpPtr) + 1; if (*(LPWORD)lpPtr == MTYPE_SUBMENU) hStartup = *((LPWORD)lpPtr+1); GlobalUnlock (hEdit); } GlobalFree (hEdit); } // Topmost window again if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); return 0; } //------------------------------------------------------------ // DoMainMenuRun - Process Run menu item //------------------------------------------------------------ LONG DoMainMenuRun (HWND hWnd, UINT idItem, HWND hwndCtl, UINT wNotifyCode) { HGLOBAL hEdit; LPSTR lpPtr; LONG lStyle; // Un-topmost window so Dlg won't be topmost lStyle = GetWindowLong (hWnd, GWL_EXSTYLE); if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); hEdit = (HGLOBAL)MyDisplayDialog(hInst, "RunBox", hWnd, (DLGPROC) RunDlgProc, 0); // Topmost window again if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); // Launch program if (hEdit) { lpPtr = GlobalLock (hEdit); if (lpPtr) { SendMessage (hWnd, MYMSG_LAUNCHPROG, 0, (LPARAM)lpPtr); GlobalUnlock (hEdit); } GlobalFree (hEdit); } return 0; } //------------------------------------------------------------ // DoMainMenuFind - Process Find menu item //------------------------------------------------------------ LONG DoMainMenuFind (HWND hWnd, UINT idItem, HWND hwndCtl, UINT wNotifyCode) { LONG lStyle; // RECT rect; // Un-topmost window so Dlg won't be topmost lStyle = GetWindowLong (hWnd, GWL_EXSTYLE); if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); // Edit startup using startup dlg template and edit item proc MyDisplayDialog(hInst, "FindBox", hWnd, (DLGPROC) FindDlgProc, 0); // Topmost window again if (lStyle & WS_EX_TOPMOST) SetWindowPos (hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); return 0; } //------------------------------------------------------------ // DoMainMenuAbout - Process About menu item //------------------------------------------------------------ LONG DoMainMenuAbout (HWND hWnd, UINT idItem, HWND hwndCtl, UINT wNotifyCode) { HWND hAbout; // Create 'Loading...' Window hAbout = CreateWindow (szLoadClass, "About WinBar", WS_POPUP, 0, 0, 300, 225, HWND_DESKTOP, NULL, hInst, (LPVOID)1); SetWindowText (hAbout, "First published in PC Magazine\nSeptember 12"\ ", 1995 (US Edition).\nFor private, non-commercial "\ "use only. All rights reserved."); EnableWindow (hWnd, FALSE); // Wait until About box dismissed. while (IsWindow (hAbout)) MyYield(); EnableWindow (hWnd, TRUE); return 0; } //------------------------------------------------------------ // DoMainMenuExit - Process Exit menu item //------------------------------------------------------------ LONG DoMainMenuExit (HWND hWnd, UINT idItem, HWND hwndCtl, UINT wNotifyCode) { SendMessage (hWnd, WM_CLOSE, 0, 0); return 0; } //------------------------------------------------------------ // WinMenuOps - Creates and destroys menu of desktop windows //------------------------------------------------------------ DWORD WinMenuOps (HGLOBAL hGlobal, UINT *pwID) { char szTemp[40]; HMENU hMenu; HWND hwndNext; INT i, sSize, sLen, sCnt = 0; UINT wHotKey; LPSTR lpPtr; LPWORD lpStart; if (!hGlobal) return 0; sSize = (INT) GlobalSize (hGlobal) - 1; lpPtr = GlobalLock (hGlobal); if (!lpPtr) return 0; lpStart = (LPWORD)lpPtr; lpPtr += sizeof (WORD); i = 0; if ((hMenu = CreatePopupMenu())) { AppendMenu (hMenu, MF_DISABLED | MF_OWNERDRAW, -2, (LPSTR)(LONG)0); hwndNext = GetWindow (GetDesktopWindow(), GW_CHILD); hwndNext = GetWindow (hwndNext, GW_HWNDLAST); while (hwndNext) { if (IsWindowVisible (hwndNext) && !(GetWindow (hwndNext, GW_OWNER))) { GetWindowText (hwndNext, lpPtr, sSize); sLen = lstrlen (lpPtr); // Don't list this window if (lstrcmp (szTitleText, lpPtr) == 0) sLen = 0; if (sLen) { wHotKey = (UINT)SendMessage (hwndNext, WM_GETHOTKEY, 0, 0); if (wHotKey) { DispHKeyText (wHotKey, szTemp, sizeof (szTemp)); if (lstrlen (szTemp)) { lstrcat (lpPtr, "\t"); lstrcat (lpPtr, szTemp); sLen = lstrlen (lpPtr); } } AppendMenu (hMenu, MF_ENABLED | MF_OWNERDRAW, (*pwID)++, lpPtr); sSize -= sLen + 1; lpPtr += sLen + 1; *((LPWORD)lpPtr)++ = MTYPE_WINITEM; *((LPWORD)lpPtr)++ = hwndNext; sCnt++; } } hwndNext = GetWindow (hwndNext, GW_HWNDPREV); } AppendMenu (hMenu, MF_DISABLED | MF_OWNERDRAW, -3, (LPSTR)(LONG)0); } *lpStart = sCnt; return MAKELONG (hMenu, hGlobal); } //------------------------------------------------------------ // IncItemPtr - Moves a pointer past an item entry //------------------------------------------------------------ LPSTR IncItemPtr (LPSTR lpPtr, BOOL fSkipName) { INT sLen; if (fSkipName) while (*(char huge *)lpPtr++); switch (*(LPWORD)lpPtr) { case MTYPE_SUBMENU: sLen = sizeof (SUBMENUDATA); break; case MTYPE_PROG: sLen = sizeof (GITEMDATA); break; case MTYPE_CPL: sLen = sizeof (CPLITEMDATA); break; case MTYPE_WINLIST: sLen = sizeof (SUBMENUDATA); break; case MTYPE_INTERNAL: sLen = sizeof (INTITEMDATA); break; case MTYPE_SEP: sLen = sizeof (SEPDATA); break; case MTYPE_WINITEM: sLen = sizeof (WINITEMDATA); break; case MTYPE_BARITEM: (char huge *)lpPtr += sizeof (BARITEMDATA); lpPtr = IncItemPtr (lpPtr, FALSE); sLen = 0; break; case MTYPE_FONTDATA: sLen = sizeof (FONTDATA); break; case MTYPE_FIELD: sLen = sizeof (SEPDATA); break; default: sLen = 0; MessageBeep(0); wsprintf (szDebug, "**** Unknown item type %x****\n", *(LPWORD)lpPtr); OutputDebugString (szDebug); break; } (char huge *)lpPtr += sLen; return lpPtr; } //------------------------------------------------------------ // AttachAccel - Adds menu string to accel list //------------------------------------------------------------ INT AttachAccel (HMENU hMenu, LPSTR lpStr, INT sPos) { PODACCEL pAccel; char ch = 0; if (sODAccelCnt == ODACCELMAX) return 0; if (!hMenu) { sODAccelCnt = 0; return 0; } if (!lpStr) { sODAccelCnt--; return 0; } // Find access key. while (*lpStr) { if (*lpStr == '&') { ch = *(lpStr+1); break; } lpStr++; } if (!ch) return 0; ch = (BYTE)(DWORD)AnsiUpper ((LPSTR)(DWORD)ch); // See if char already in list pAccel = pODAccel; pAccel += sODAccelCnt; // Add key to list pAccel->hMenu = hMenu; pAccel->chKey = ch; pAccel->chPos = (char)sPos; sODAccelCnt++; return 0; } //------------------------------------------------------------ // UDefSubMenu - Creates and destroys user defined submenus //------------------------------------------------------------ INT UDefSubMenu (HMENU hMenu, HGLOBAL hGroup, BOOL fCreate, UINT *pwID) { DWORD dwData; LPWORD lpPtr; LPSTR lpStr; HGLOBAL hSubMem; HMENU hSubMenu; INT i, sCnt; INT sBreakCnt; if (!hGroup) return 0; lpPtr = (LPWORD) GlobalLock (hGroup); if (!lpPtr) return 0; i = GetStatusBarHeight (hMain); sBreakCnt = (GetSystemMetrics(SM_CYSCREEN) - i) / (i - 2); sCnt = *lpPtr++; if (sCnt) { for (i = 0; i < sCnt; i++) { // Add a menu break if menu is too long for screen if (fCreate && (i >= sBreakCnt) && (i % sBreakCnt == 0)) { AppendMenu (hMenu, MF_MENUBREAK | MF_DISABLED | MF_OWNERDRAW, -2, 0); } // Save ptr to name lpStr = (LPSTR) lpPtr; if (fCreate) AttachAccel (hMenu, lpStr, i+1); // Move ptr past name lpPtr = (LPWORD)(lpStr + lstrlen (lpStr) + 1); // Switch on menu item type switch (*lpPtr) { case MTYPE_SUBMENU: // Get handle to memory blk containing menu desc hSubMem = ((LPSUBMENUDATA)lpPtr)->hGlobal; if (fCreate) { hSubMenu = CreateMenu (); AppendMenu (hSubMenu, MF_DISABLED | MF_OWNERDRAW, -2, (LPSTR)(LONG)0); } UDefSubMenu (hSubMenu, hSubMem, fCreate, pwID); if (fCreate) { AppendMenu (hSubMenu, MF_DISABLED | MF_OWNERDRAW, -3, (LPSTR)(LONG)0); AppendMenu (hMenu, MF_ENABLED | MF_OWNERDRAW | MF_POPUP, hSubMenu, lpStr); } break; case MTYPE_CPL: if (fCreate) AppendMenu (hMenu, MF_ENABLED | MF_OWNERDRAW, (*pwID)++, lpStr); break; case MTYPE_PROG: if (fCreate) AppendMenu (hMenu, MF_ENABLED | MF_OWNERDRAW, (*pwID)++, lpStr); break; case MTYPE_WINLIST: dwData = WinMenuOps (hWinData, pwID); if (fCreate) { AppendMenu (hMenu, MF_ENABLED | MF_OWNERDRAW | MF_POPUP, LOWORD (dwData), lpStr); ((LPSUBMENUDATA)lpPtr)->hGlobal = HIWORD (dwData); } else { GlobalUnlock (((LPSUBMENUDATA)lpPtr)->hGlobal); } break; case MTYPE_INTERNAL: if (fCreate) AppendMenu (hMenu, MF_ENABLED | MF_OWNERDRAW, (*pwID)++, lpStr); break; case MTYPE_SEP: if (fCreate) { AppendMenu (hMenu, MF_DISABLED | MF_OWNERDRAW, -4, (LPSTR)(LONG)-4); (*pwID)++; } break; } lpPtr = (LPWORD) IncItemPtr ((LPSTR)lpPtr, FALSE); } } return sCnt; } //------------------------------------------------------------ // UDefMenuOps - Creates and destroys user defined menus. //------------------------------------------------------------ DWORD UDefMenuOps (HGLOBAL hGlobal, BOOL fCreate) { HMENU hMenu; LPWORD lpPtr; UINT wID = 1; lpPtr = (LPWORD) GlobalLock (hGlobal); if (!lpPtr) return 0; if (*lpPtr) { if (fCreate) { if (hMenu = CreatePopupMenu()) { AppendMenu (hMenu, MF_DISABLED | MF_OWNERDRAW, -2, (LPSTR)(LONG)-2); if (UDefSubMenu (hMenu, hGlobal, fCreate, &wID) == 0) { DestroyMenu (hMenu); hMenu = 0; } else { AppendMenu (hMenu, MF_DISABLED | MF_OWNERDRAW, -3, (LPSTR)(LONG)-3); } } } else { UDefSubMenu (0, hGlobal, fCreate, &wID); // Unlock twice to even count; GlobalUnlock (hGlobal); GlobalUnlock (hGlobal); } } return MAKELONG (hMenu, hGlobal); } //------------------------------------------------------------ // ScanUDefMenu - Converts a menu id into a pointer to menu // item data. //------------------------------------------------------------ LPBYTE ScanUDefMenu (HGLOBAL hGroup, UINT *pwID, HGLOBAL *hFound) { LPWORD lpPtr; HGLOBAL hSubMem; LPSTR lpStr, lpItem; INT i, sCnt; if (hGroup == 0) return 0; lpPtr = (LPWORD) GlobalLock (hGroup); if (lpPtr == 0) return 0; sCnt = *lpPtr++; if (sCnt) { for (i = 0; i < sCnt; i++) { // Save ptr to name lpStr = (LPSTR) lpPtr; // Move ptr past name lpPtr = (LPWORD)(lpStr + lstrlen (lpStr) + 1); if ((*lpPtr == MTYPE_SUBMENU) || (*lpPtr == MTYPE_WINLIST)) { // Get handle to memory blk containing menu desc hSubMem = ((LPSUBMENUDATA)lpPtr)->hGlobal; lpItem = ScanUDefMenu (hSubMem, pwID, hFound); if (lpItem) { GlobalUnlock (hGroup); return lpItem; } lpPtr = (LPWORD)((LPSTR)lpPtr + sizeof (SUBMENUDATA)); } else { (*pwID)--; if (*pwID) lpPtr = (LPWORD) IncItemPtr ((LPSTR)lpPtr, FALSE); else { *hFound = hGroup; return lpStr; } } } } GlobalUnlock (hGroup); return 0; } //------------------------------------------------------------ // ProcessPick - Act on a menu item pick //------------------------------------------------------------ DWORD ProcessPick (HWND hWnd, LPSTR lpStr) { LPWORD lpPtr; if (lpStr) { lpPtr = (LPWORD)(lpStr + lstrlen (lpStr) + 1); // If pointing to a bar item, skip extra data if (*lpPtr == MTYPE_BARITEM) lpPtr = (LPWORD)((LPSTR) lpPtr + sizeof (BARITEMDATA)); switch (*lpPtr) { case MTYPE_SUBMENU: break; case MTYPE_CPL: //OutputDebugString ("Cpl cmd: --"); //OutputDebugString (((LPCPLITEMDATA)lpPtr)->szCmd); //OutputDebugString ("--\n"); WinExec (((LPCPLITEMDATA)lpPtr)->szCmd, SW_SHOWNORMAL); break; case MTYPE_PROG: SendMessage (hWnd, MYMSG_LAUNCHPROG, 0, (LPARAM)lpStr); break; case MTYPE_WINITEM: SetActiveWindow (((LPWINITEMDATA)lpPtr)->hWnd); if (IsIconic (((LPWINITEMDATA)lpPtr)->hWnd)) ShowWindow (((LPWINITEMDATA)lpPtr)->hWnd, SW_RESTORE); break; case MTYPE_INTERNAL: PostMessage (hMain, WM_COMMAND, ((LPINTITEMDATA)lpPtr)->wID, 0); break; } } return 0; } //------------------------------------------------------------ // Draw3DBorder //------------------------------------------------------------ void Draw3DBorder (HDC hdc, HPEN hDPen, HPEN hNPen, HPEN hLPen, RECT far *rect) { HPEN hOldPen; hOldPen = SelectObject (hdc, hLPen); MoveTo (hdc, rect->left, rect->top); LineTo (hdc, rect->left, rect->bottom); MoveTo (hdc, rect->left+1, rect->top); LineTo (hdc, rect->left+1, rect->bottom); SelectObject (hdc, hDPen); MoveTo (hdc, rect->right, rect->bottom); LineTo (hdc, rect->right, rect->top); MoveTo (hdc, rect->right-1, rect->bottom); LineTo (hdc, rect->right-1, rect->top); SelectObject (hdc, hOldPen); return; } //------------------------------------------------------------ // ShutDownStuff - Perform shutdown processing //------------------------------------------------------------ INT ShutdownStuff (HWND hWnd) { HCURSOR hOld; char szTemp[128]; HFONT hFont; UINT wHotKey; INT sRet, i; sRet = GetKeyState (VK_SHIFT) & 0x8000; if ((fFlags & FLAG_SAVEONEXIT) || sRet) { hOld = SetCursor (LoadCursor (NULL, IDC_WAIT)); hFont = (HFONT)SendDlgItemMessage (hWnd, IDD_STATBAR, WM_GETFONT, 0, 0); wHotKey = (UINT)SendMessage (hWnd, WM_GETHOTKEY, 0, 0); i = GetModuleFileName (hInst, szTemp, sizeof (szTemp)); lstrcpy (&szTemp[i-3], "DAT"); SavetoFile(hBarData, hStartup, hFont, wHotKey, szTemp); SetCursor (hOld); if (sRet) return 0; } sRet = IDYES; if (fFlags & FLAG_ASKONEXIT) { // If we are the shell, change exit message if (fFlags & FLAG_SHELL) { lstrcpy (szTemp, "This will end your Windows session."); i = MB_ICONEXCLAMATION | MB_OKCANCEL | MB_SYSTEMMODAL; } else { lstrcpy (szTemp, "Do you wish to exit "); lstrcat (szTemp, szAppName); lstrcat (szTemp, "?"); i = MB_ICONQUESTION | MB_YESNO; } sRet = MessageBox (hWnd, szTemp, szTitleText, i); if (sRet == IDOK) sRet = IDYES; } if (sRet != IDYES) return 0; // If shell, shutdown Windows. This call will only return if // shutdown fails. if (fFlags & FLAG_SHELL) { fFlags |= FLAG_SHUTDOWN; ExitWindows (0, 0); // If we return here, someone failed the shutdown so we stay active. fFlags &= ~FLAG_SHUTDOWN; return 0; } return 1; } //------------------------------------------------------------ // InsertOverwrite - Inserts or overwrites an item in a menu. //------------------------------------------------------------ INT InsertOverwrite (LPSTR lpStart, LPSTR lpSub, LPSTR lpEdit, INT sCnt, INT sLen, BOOL fInsert) { INT rc = 0, sGap; LPSTR lpSub1; // Adjust size of old entry to fit size of edited entry. lpSub1 = IncItemPtr (lpEdit, TRUE); if (fInsert && sLen) sGap = lpSub1 - lpEdit + IncItemPtr (lpSub, TRUE) - lpSub; else sGap = lpSub1 - lpEdit; if (SizeEntrySpace (lpSub, sLen - sCnt - 1, sGap)) { // If insert, skip past current selection if (fInsert) { if (sLen) lpSub = IncItemPtr (lpSub, TRUE); // Inc count (*(LPWORD)lpStart)++; } // Copy entry into space created while (lpEdit < lpSub1) *lpSub++ = *lpEdit++; } else rc = ERR_NOMEMORY; return rc; } //------------------------------------------------------------ // AddEditItem - Add and Edit functions for edit dialogs //------------------------------------------------------------ INT AddEditItem (HWND hWnd, HGLOBAL hSubMem, UINT wID, BOOL fInsert, INT sMode) { LPSTR lpStart, lpSub, lpSub1, lpEdit, lpTpl; char huge *hpSave; INT i, rc = 0, sLen, sCnt; EDITITEM ei; HGLOBAL hEdit, hSave; lpSub = GlobalLock (hSubMem); if (!lpSub) return ERR_NOMEMORY; // Get length of submenu lpStart = lpSub; sLen = *((LPINT)lpSub)++; if (sLen == 0) fInsert = TRUE; // See which entry in the listbox is selected sCnt = (INT)SendDlgItemMessage (hWnd, wID, LB_GETCURSEL, 0, 0); if (sCnt == LB_ERR) { if (fInsert) if (sLen) sCnt = sLen - 1; else sCnt = 0; else { GlobalUnlock (hSubMem); return ERR_CANCELED; } } // Scan to insert/edit point for (i = 0; i < sCnt; i++) lpSub = IncItemPtr (lpSub, TRUE); if (fInsert) lpTpl = 0; else lpTpl = lpSub; // Edit entry with dialog. If bar item, use different dialog lpSub1 = lpSub; if (sLen) lpSub1 += lstrlen (lpSub) + 1; if (*(LPWORD)lpSub1 == MTYPE_BARITEM) hEdit = MyDisplayDialog(hInst, "EditBar", hWnd, (DLGPROC) EditBarDlgProc, (LPARAM)lpTpl); else { ei.lParam = (LPARAM)lpTpl; if (sMode) { ei.sMode = 2; hEdit = MyDisplayDialog(hInst, "EditStartItem", hWnd, (DLGPROC) EditItemDlgProc, (LPARAM)(LPEDITITEM)&ei); } else { // If Submenu, save the current menu config if (*(LPWORD)lpSub1 == MTYPE_SUBMENU) hSave = SavetoMem (((LPSUBMENUDATA)lpSub1)->hGlobal); else hSave = 0; ei.sMode = 0; hEdit = MyDisplayDialog(hInst, "EditItem", hWnd, (DLGPROC) EditItemDlgProc, (LPARAM)(LPEDITITEM)&ei); if (hSave) { if (hEdit == 1) { // Get old data hpSave = GlobalLock (hSave); if (hpSave) { // Free modified but discarded submenu GlobalUnlock (((LPSUBMENUDATA)lpSub1)->hGlobal); FreeMenuBlk (((LPSUBMENUDATA)lpSub1)->hGlobal); // Restore menu struct from save blk ((LPSUBMENUDATA)lpSub1)->hGlobal = RestoreMenufromMem (&hpSave); } } GlobalUnlock (hSave); GlobalFree (hSave); } } } // If submenu edit canceled, make it look like no changes if (hEdit == 1) hEdit = 0; // If item edited... if (hEdit) { lpEdit = GlobalLock (hEdit); if (lpEdit) { rc = InsertOverwrite (lpStart, lpSub, lpEdit, sCnt, sLen, fInsert); // Refill list box FillSubmenuBox (hWnd, hSubMem, wID); SendDlgItemMessage (hWnd, wID, LB_SETCURSEL, sCnt, 0); // Discard buffer created by edit entry dialog box GlobalUnlock (hEdit); } GlobalFree (hEdit); } else rc = ERR_CANCELED; GlobalUnlock (hSubMem); return rc; } //------------------------------------------------------------ // CutCopyItem - Cut and Copy functions for edit dialogs //------------------------------------------------------------ INT CutCopyItem (HWND hWnd, HGLOBAL hSubMem, UINT wID, BOOL fCut) { LPSTR lpStart, lpSub, lpSub1; INT i, j, rc = 0, sLen, sCnt, sGap; lpSub = GlobalLock (hSubMem); if (!lpSub) return ERR_NOMEMORY; // Get length of submenu lpStart = lpSub; sLen = *((LPINT)lpSub)++; // See which entry in the listbox is selected sCnt = (INT)SendDlgItemMessage (hWnd, wID, LB_GETCURSEL, 0, 0); if (sCnt == LB_ERR) { GlobalUnlock (hSubMem); return ERR_CANCELED; } // Scan to cut/copy point for (i = 0; i < sCnt; i++) lpSub = IncItemPtr (lpSub, TRUE); // copy item to clipboard rc = SavetoClip (hWnd, lpSub); if (rc == 0) { if (fCut) { // If submenu, free all submenu blocks. Chk for // and skip bardata structure if present. lpSub1 = lpSub; lpSub1 += lstrlen (lpSub1) + 1; if (((LPSUBMENUDATA)lpSub1)->sType == MTYPE_BARITEM) lpSub1 += sizeof (BARITEMDATA); if (((LPSUBMENUDATA)lpSub1)->sType == MTYPE_SUBMENU) FreeMenuBlk (((LPSUBMENUDATA)lpSub1)->hGlobal); // Delete item by copying next items over it lpSub1 = IncItemPtr (lpSub, TRUE); for (i = sCnt; i < sLen - 1; i++) { sGap = IncItemPtr (lpSub1, TRUE) - lpSub1; for (j = 0; j < sGap; j++) *lpSub++ = *lpSub1++; } // Dec count of items (*(LPWORD)lpStart)--; // Refill list box FillSubmenuBox (hWnd, hSubMem, wID); SendDlgItemMessage (hWnd, wID, LB_SETCURSEL, sCnt, 0); } } GlobalUnlock (hSubMem); return rc; } //------------------------------------------------------------ // PasteItem - Paste function for edit dialogs //------------------------------------------------------------ INT PasteItem (HWND hWnd, HGLOBAL hSubMem, UINT wID, BOOL fBar) { LPSTR lpStart, lpSub, lpClip, lpTemp; INT i, rc = 0, sLen, sCnt; HGLOBAL hClip; lpSub = GlobalLock (hSubMem); if (!lpSub) return ERR_NOMEMORY; // Get length of submenu lpStart = lpSub; sLen = *((LPINT)lpSub)++; // See which entry in the listbox is selected sCnt = (INT)SendDlgItemMessage (hWnd, wID, LB_GETCURSEL, 0, 0); if (sCnt == LB_ERR) { if (sLen) sCnt = sLen - 1; else sCnt = 0; } // Scan to insert/edit point for (i = 0; i < sCnt; i++) lpSub = IncItemPtr (lpSub, TRUE); // Get data from clipboard hClip = ReadfromClip (hWnd); lpClip = GlobalLock (hClip); if (lpClip) { // If pasting from menu to bar or bar to menu, add or delete // bar item structure. lpTemp = lpClip; lpTemp += lstrlen (lpTemp) + 1; if (((LPSUBMENUDATA)lpTemp)->sType != MTYPE_BARITEM) { if (fBar) { // Make room for BARITEM structure for (i = sizeof (GITEMDATA); i >= 0; i--) *(lpTemp + i + sizeof (BARITEMDATA)) = *(lpTemp + i); // Init BARITEM structure ((LPBARITEMDATA)lpTemp)->sType = MTYPE_BARITEM; ((LPBARITEMDATA)lpTemp)->sDisplayMode = DISP_TEXT; ((LPBARITEMDATA)lpTemp)->szIconFName[0] = '\0'; ((LPBARITEMDATA)lpTemp)->wIconIndex = 0; } } else { if (!fBar) { // Delete BARITEM structure for (i = 0; i < sizeof (GITEMDATA); i++) *(lpTemp + i) = *(lpTemp + i + sizeof (BARITEMDATA)); } } rc = InsertOverwrite (lpStart, lpSub, lpClip, sCnt, sLen, TRUE); // Discard pasted data item. Its been copyed to menu GlobalUnlock (hClip); GlobalFree (hClip); // Refill list box FillSubmenuBox (hWnd, hSubMem, wID); SendDlgItemMessage (hWnd, wID, LB_SETCURSEL, sCnt, 0); } else rc = ERR_BADCLIPREAD; GlobalUnlock (hSubMem); return rc; } //------------------------------------------------------------ // SetPasteButton - Enable/disable paste button //------------------------------------------------------------ void SetPasteButton (HWND hWnd, UINT wID, INT sMode) { HGLOBAL hClip; LPSTR lpClip; BOOL fEnable = FALSE; // Enable Paste button if clipboard format available if (OpenClipboard (hWnd)) { if (IsClipboardFormatAvailable (hWBClipFmt)) { // If editing the startup list, only allow // programs to be pasted. if (sMode == 1) { hClip = GetClipboardData (hWBClipFmt); lpClip = GlobalLock (hClip); if (lpClip) { lpClip += lstrlen (lpClip) + 1; if (*(LPWORD)lpClip == MTYPE_PROG) fEnable = TRUE; GlobalUnlock (hClip); } } else fEnable = TRUE; } CloseClipboard(); } EnableWindow (GetDlgItem (hWnd, wID), fEnable); return; } //------------------------------------------------------------ // CommonRegenBar - Common code used by config ctrls //------------------------------------------------------------ BOOL CommonRegenBar (HWND hWnd, HFONT hNewFont, HGLOBAL hOld, INT sResults) { char huge *hpSave; HGLOBAL hRestore; LOGFONT ofm; HDC hdc; HFONT hFont; INT rc; BOOL fChanged = FALSE; if (sResults) { if (sResults != ERR_CANCELED) PrintError (hWnd, sResults); } else { //Get current font from status bar to init Font Dlg box hFont = (HANDLE)SendDlgItemMessage (GetParent(hWnd), IDD_STATBAR, WM_GETFONT, 0, 0); //wsprintf (szDebug, "Current Font: %d New Font: %d\n", hFont, hNewFont); //OutputDebugString (szDebug); if (hFont == 0) GetObject (GetStockObject (SYSTEM_FONT), sizeof (ofm), &ofm); else GetObject (hFont, sizeof (ofm), &ofm); // Create new bar with changed params rc = (INT)SendMessage (GetParent (hWnd), MYMSG_CREATEBAR, hNewFont, MAKELONG (hBarData, 1)); if (rc) { //wsprintf (szDebug, "Error creating statusbar. rc = %d\n", rc); //OutputDebugString (szDebug); PrintError (hWnd, rc); if (!(hFont = CreateFontIndirect (&ofm))) { hdc = GetDC (NULL); hFont = MakeFont (hdc, "Helv", 8, FW_BOLD, 0); ReleaseDC (NULL, hdc); } // Restore menu struct from save blk and recreate bar hpSave = GlobalLock (hOld); hRestore = RestoreMenufromMem (&hpSave); if (!hRestore) MessageBox (hWnd, "Bad Restore!", "Error",MB_OK); else SendMessage (GetParent (hWnd), MYMSG_CREATEBAR, hFont, MAKELONG (hRestore, 1)); } else { fChanged = TRUE; } } GlobalFree (hOld); SetFocus (hWnd); return fChanged; } //------------------------------------------------------------ // GetCheckBoxStates - //------------------------------------------------------------ UINT GetCheckBoxStates (HWND hWnd) { UINT fTemp; fTemp = fFlags; fTemp &= ~(FLAG_SAVEONEXIT | FLAG_ASKONEXIT | FLAG_FASTMENU | FLAG_ALWAYSONTOP); if (IsDlgButtonChecked (hWnd, IDD_ASKONEXIT)) fTemp |= FLAG_ASKONEXIT; if (IsDlgButtonChecked (hWnd, IDD_SAVEONEXIT)) fTemp |= FLAG_SAVEONEXIT; if (IsDlgButtonChecked (hWnd, IDD_FASTMENU)) fTemp |= FLAG_FASTMENU; if (IsDlgButtonChecked (hWnd, IDD_ONTOP)) fTemp |= FLAG_ALWAYSONTOP; return fTemp; } //============================================================ // ConfigDlgProc - Config dialog box dialog procedure //============================================================ BOOL CALLBACK ConfigDlgProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { static HGLOBAL hSubMem; static HGLOBAL hSave; static BOOL fChanged = FALSE; static UINT fOldFlags; static LOGFONT fm; HGLOBAL hTemp; WNDPROC lpfnOldEditWndProc; LPSTR lpSub, lpSub1; char huge *hpSave; HGLOBAL hNew, hData; INT i, sCnt; HFONT hFont, hFontOld; COLORREF rgbColor; switch (wMsg) { case WM_INITDIALOG: // Copy bar handle hSubMem = hBarData; // Save the current bar config hSave = SavetoMem (hSubMem); fOldFlags = fFlags; hFont = (INT)SendDlgItemMessage (GetParent(hWnd), IDD_STATBAR, WM_GETFONT, 0, 0); GetObject (hFont, sizeof (fm), &fm); // Set tab stops for submenu list i = 70; SendDlgItemMessage (hWnd, IDD_LIST, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&i); if (hSubMem) { FillSubmenuBox (hWnd, hSubMem, IDD_LIST); // Resize blk to allow for editing hTemp = GlobalReAlloc (hSubMem, 0x10000, GMEM_ZEROINIT); if (hTemp) hSubMem = hTemp; else { MessageBox (NULL, "Not enough memory", szTitleText, MB_OK | MB_ICONSTOP); EndDialog (hWnd, 0); } } SendDlgItemMessage (hWnd, IDD_LIST, LB_SETCURSEL, 0, 0); PostMessage (hWnd, WM_COMMAND, IDD_LIST, MAKELPARAM (0, LBN_SELCHANGE)); // Subclass hotkey entry field edit box. Put the old edit proc in // the user dword of the window structure so that the subclassed // edit box can find it. lpfnOldEditWndProc = MySubClassWindow (GetDlgItem (hWnd, IDD_HOTKEY), lpfnHKeyFieldProc); SetWindowLong (hWnd, DWL_USER, (LONG)lpfnOldEditWndProc); // Set hotkey text i = (INT) SendMessage (GetParent (hWnd), WM_GETHOTKEY, 0, 0); if (i) SendDlgItemMessage (hWnd, IDD_HOTKEY, WM_USER+101, i, 0); // Set checkboxes CheckDlgButton (hWnd, IDD_ASKONEXIT, (fFlags & FLAG_ASKONEXIT) ? 1 : 0); CheckDlgButton (hWnd, IDD_SAVEONEXIT, (fFlags & FLAG_SAVEONEXIT) ? 1 : 0); CheckDlgButton (hWnd, IDD_FASTMENU, (fFlags & FLAG_FASTMENU) ? 1 : 0); CheckDlgButton (hWnd, IDD_ONTOP, (fFlags & FLAG_ALWAYSONTOP) ? 1 : 0); // Enable Paste button if clipboard format available SetPasteButton (hWnd, IDD_PASTE, 0); SetFocus (GetDlgItem (hWnd, IDD_LIST)); // Position window mid down toward left side { INT x, y; RECT rect; x = GetSystemMetrics (SM_CXSCREEN) / 2; y = GetSystemMetrics (SM_CYSCREEN) / 2; GetWindowRect (hWnd, &rect); SetWindowPos (hWnd, NULL, max (x - (rect.right - rect.left), 0), y - (rect.bottom - rect.top) / 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } return TRUE; case WM_COMMAND: switch (wParam) { case IDD_LIST: // Don't allow main separator field to be edited or deleted switch (HIWORD (lParam)) { case LBN_DBLCLK: case LBN_SELCHANGE: sCnt = (INT)SendDlgItemMessage (hWnd, IDD_LIST, LB_GETCURSEL, 0, 0); if (sCnt == LB_ERR) { EnableWindow (GetDlgItem (hWnd, IDD_EDIT), FALSE); EnableWindow (GetDlgItem (hWnd, IDD_CUT), FALSE); EnableWindow (GetDlgItem (hWnd, IDD_COPY), FALSE); return TRUE; } lpSub = GlobalLock (hSubMem); lpSub += 2; for (i = 0; i < sCnt; i++) lpSub = IncItemPtr (lpSub, TRUE); lpSub += lstrlen (lpSub) + 1; if (((LPBARITEMDATA)lpSub)->sDisplayMode == DISP_MAINSEP) { EnableWindow (GetDlgItem (hWnd, IDD_EDIT), FALSE); EnableWindow (GetDlgItem (hWnd, IDD_CUT), FALSE); EnableWindow (GetDlgItem (hWnd, IDD_COPY), FALSE); return TRUE; } EnableWindow (GetDlgItem (hWnd, IDD_EDIT), TRUE); EnableWindow (GetDlgItem (hWnd, IDD_CUT), TRUE); EnableWindow (GetDlgItem (hWnd, IDD_COPY), TRUE); if (HIWORD (lParam) == LBN_DBLCLK) PostMessage (hWnd, WM_COMMAND, IDD_EDIT, MAKELPARAM (0, BN_CLICKED)); return TRUE; } break; case IDD_ADD: case IDD_EDIT: hData = SavetoMem (hSubMem); if (wParam == IDD_ADD) i = AddEditItem (hWnd, hSubMem, IDD_LIST, TRUE, 0); else i = AddEditItem (hWnd, hSubMem, IDD_LIST, FALSE, 0); //Build bar in new image if (CommonRegenBar (hWnd, 0, hData, i)) fChanged = TRUE; // Enable Paste button if clipboard format available SetPasteButton (hWnd, IDD_PASTE, 0); return TRUE; case IDD_CUT: case IDD_COPY: hData = SavetoMem (hSubMem); if (wParam == IDD_CUT) i = CutCopyItem (hWnd, hSubMem, IDD_LIST, TRUE); else i = CutCopyItem (hWnd, hSubMem, IDD_LIST, FALSE); //Build bar in new image if (CommonRegenBar (hWnd, 0, hData, i)) fChanged = TRUE; // Enable Paste button if clipboard format available SetPasteButton (hWnd, IDD_PASTE, 0); return TRUE; case IDD_PASTE: hData = SavetoMem (hSubMem); i = PasteItem (hWnd, hSubMem, IDD_LIST, TRUE); //Build bar in new image if (CommonRegenBar (hWnd, 0, hData, i)) fChanged = TRUE; return TRUE; case IDD_SETFONT: { LOGFONT ofm; hData = SavetoMem (hSubMem); //Get current font from status bar to init Font Dlg box hFontOld = (HFONT)SendDlgItemMessage (GetParent(hWnd), IDD_STATBAR, WM_GETFONT, 0, 0); if (hFontOld == 0) GetObject (GetStockObject (SYSTEM_FONT), sizeof (ofm), &ofm); else GetObject (hFontOld, sizeof (ofm), &ofm); rgbColor = RGB (0, 0, 0); if (MyGetFont (hWnd, &ofm, &i, &rgbColor, CF_INITTOLOGFONTSTRUCT | CF_ANSIONLY)) { // If user selects font, create it create new statbar // using it. if (hFont = CreateFontIndirect (&ofm)) if (CommonRegenBar (hWnd, hFont, hData, 0)) fChanged = TRUE; } } return TRUE; case IDD_FASTMENU: if (HIWORD (lParam) != BN_CLICKED) break; fFlags &= ~FLAG_FASTMENU; if (IsDlgButtonChecked (hWnd, IDD_FASTMENU)) fFlags |= FLAG_FASTMENU; SendMessage (GetParent (hWnd), MYMSG_CREATEBAR, 0, 0); SetFocus (hWnd); fChanged = TRUE; return TRUE; case IDD_MIGRATE: // Edit icon selection hNew = MyDisplayDialog(hInst, "ListGroupBox", hWnd, (DLGPROC) ListGroupDlgProc, 0); if (hNew) { char szTemp[256], *pTemp; char szGName[64]; // lpSub = (LPGITEMDATA)GlobalLock (hNew); lpSub = GlobalLock (hNew); // Get data for each item in group file lstrcpy (szTemp, lpSub); hData = GetGroupData (szTemp, szGName); if (hData) { // Copy group name lstrcpy (szTemp, szGName); pTemp = szTemp + lstrlen (szTemp) + 1; // Save group memory handle *((WORD *)pTemp)++ = MTYPE_SUBMENU; *((WORD *)pTemp)++ = hData; // copy item to clipboard i = SavetoClip (hWnd, szTemp); if (i) PrintError (hWnd, i); else { lstrcpy (szTemp, "Program Manager group: "); lstrcat (szTemp, szGName); lstrcat (szTemp, " copyed to the clipboard.\n"); lstrcat (szTemp, "Use Paste button to insert into a menu."); MessageBox (hWnd, szTemp, szTitleText, MB_ICONINFORMATION | MB_OK); } GlobalUnlock (hData); GlobalFree (hData); } GlobalUnlock (hNew); GlobalFree (hNew); SetPasteButton (hWnd, IDD_PASTE, 0); } return TRUE; case IDD_SAVE: { char szTemp[128]; HCURSOR hOld; UINT wHotKey; // Get checkbox states fFlags = GetCheckBoxStates (hWnd); hOld = SetCursor (LoadCursor (NULL, IDC_WAIT)); i = GetModuleFileName (hInst, szTemp, sizeof (szTemp)); lstrcpy (&szTemp[i-3], "DAT"); hFont = (HFONT)SendDlgItemMessage (GetParent(hWnd), IDD_STATBAR, WM_GETFONT, 0, 0); wHotKey = (UINT)SendMessage (hWnd, WM_GETHOTKEY, 0, 0); SavetoFile(hBarData, hStartup, hFont, wHotKey, szTemp); SetCursor (hOld); } break; case IDOK: // Get hot key i = (INT)SendDlgItemMessage (hWnd, IDD_HOTKEY, WM_USER+100, 0, 0); SendMessage (GetParent (hWnd), WM_SETHOTKEY, i, 0); // Get checkbox states fFlags = GetCheckBoxStates (hWnd); EndDialog(hWnd, 1); return TRUE; case IDCANCEL: i = IDNO; if (fOldFlags != GetCheckBoxStates (hWnd)) fChanged = TRUE; if (fChanged) { i = MessageBox (hWnd, "Discard changes?",szAppName, MB_ICONQUESTION | MB_YESNOCANCEL); if (i == IDCANCEL) return TRUE; } // If user discards changes, restore from saved mem blk if (i != IDYES) { PostMessage (hWnd, WM_COMMAND, IDOK, 0); return TRUE; } // Get old data fFlags = fOldFlags; hpSave = GlobalLock (hSave); if (hpSave) { GlobalUnlock (hSubMem); FreeMenuBlk (hSubMem); hSubMem = 0; // Restore menu struct from save blk and recreate bar hNew = RestoreMenufromMem (&hpSave); if (!hNew) MessageBox (hWnd, "Bad Restore!", "Error",MB_OK); else { hFont = CreateFontIndirect (&fm); SendMessage (GetParent (hWnd), MYMSG_CREATEBAR, hFont, MAKELONG (hNew, 1)); } } GlobalUnlock (hSave); EndDialog(hWnd, 0); return TRUE; } return TRUE; case WM_DESTROY: if (hSubMem) { // Resize menu block to min necessary for data lpSub = GlobalLock (hSubMem); sCnt = *(LPWORD)lpSub; lpSub1 = lpSub + 2; for (i = 0; i < sCnt; i++) lpSub1 = IncItemPtr (lpSub1, TRUE); GlobalUnlock (hSubMem); hBarData = hSubMem; hTemp = GlobalReAlloc (hSubMem, lpSub1 - lpSub, 0); if (hTemp) hBarData = hTemp; } GlobalFree (hSave); // Unsubclass hotkey window lpfnOldEditWndProc = (WNDPROC)GetWindowLong (hWnd, DWL_USER); MySubClassWindow (GetDlgItem (hWnd, IDD_HOTKEY), lpfnOldEditWndProc); return FALSE; } return FALSE; } //============================================================ // EditBarDlgProc - Item Edit dialog box dialog procedure //============================================================ BOOL CALLBACK EditBarDlgProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { static HGLOBAL hItem = 0; static LPBARITEMDATA lpBarItem; static LPSTR lpItem; LPGITEMDATA lpProg; GITEMDATA Prog; INT i, rc, sCnt; HGLOBAL hEdit; LPSTR lpEdit; HWND hCtl; HICON hIcon; switch (wMsg) { case WM_INITDIALOG: // Fill in entries for special cmd list for (i = 0; i < dim (DispTypes); i++) { SendDlgItemMessage (hWnd, IDD_BSPECTYPE, CB_ADDSTRING, 0, (LPARAM)(LPSTR)DispTypes[i].szName); } SendDlgItemMessage (hWnd, IDD_BSPECTYPE, CB_SETCURSEL, 0, 0); // Hide all property controls for (i = IDD_BITEMNAMET; i < IDD_BSPECTYPE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_HIDE); // Create a template blk hItem = GlobalAlloc (GHND, 128 + sizeof (BARITEMDATA) + sizeof (GITEMDATA)); lpItem = GlobalLock (hItem); // If initializer passed, init box ctls if (lParam) { // Copy name lstrcpy (lpItem, (LPSTR)lParam); lpBarItem = (LPBARITEMDATA)(lpItem + lstrlen (lpItem) + 1); lParam = (LPARAM) lParam + lstrlen ((LPSTR)lParam) + 1; // Abort if bar item not being edited if (*(LPWORD)lParam != MTYPE_BARITEM) { GlobalUnlock (hItem); GlobalFree (hItem); EndDialog(hWnd, 0); return TRUE; } // Copy bar item structure _fmemmove (lpBarItem, (LPSTR)lParam, sizeof (BARITEMDATA)); // Copy sub item attached to bar item. lParam += sizeof (BARITEMDATA); sCnt = (INT)(IncItemPtr ((LPSTR)lParam, FALSE) - (LPSTR)lParam); _fmemmove ((LPSTR)lpBarItem + sizeof (BARITEMDATA), (LPSTR)lParam, sCnt); // Init text name field SetDlgItemText (hWnd, IDD_BITEMNAME, lpItem); // Init icon field PostMessage (hWnd, WM_COMMAND, IDD_BICONPICT, 0); // Set mode dep on bar structure switch (lpBarItem->sDisplayMode) { case DISP_TEXT: PostMessage (hWnd, WM_COMMAND, IDD_BTEXT, 0); break; case DISP_ICON: PostMessage (hWnd, WM_COMMAND, IDD_BICON, 0); break; default: for (i = 0; i < dim (DispTypes); i++) { if (lpBarItem->sDisplayMode == DispTypes[i].sMode) break; } SendDlgItemMessage (hWnd, IDD_BSPECTYPE, CB_SETCURSEL, i, 0); PostMessage (hWnd, WM_COMMAND, IDD_BSPEC, 0); break; } } else { // No initialization, set default inits. *lpItem = '\0'; lpBarItem = (LPBARITEMDATA)(lpItem + 1); lpBarItem->sType = MTYPE_BARITEM; lpBarItem->sDisplayMode = DISP_TEXT; lpBarItem->szIconFName[0] = '\0'; lpBarItem->wIconIndex = 0; lpProg = (LPGITEMDATA)((LPSTR)lpBarItem + sizeof (BARITEMDATA)); lpProg->sType = MTYPE_SEP; PostMessage (hWnd, WM_COMMAND, IDD_BTEXT, 0); } lpProg = (LPGITEMDATA)((LPSTR)lpBarItem + sizeof (BARITEMDATA)); switch (lpProg->sType) { case MTYPE_SUBMENU: SetDlgItemText (hWnd, IDD_BACTIONT, "Display Menu"); break; case MTYPE_PROG: SetDlgItemText (hWnd, IDD_BACTIONT, "Launch Program"); break; case MTYPE_WINLIST: SetDlgItemText (hWnd, IDD_BACTIONT, "Display Window List"); break; case MTYPE_CPL: SetDlgItemText (hWnd, IDD_BACTIONT, "Open Control Panel Applet"); break; case MTYPE_INTERNAL: SetDlgItemText (hWnd, IDD_BACTIONT, "WinBar Command"); break; default: SetDlgItemText (hWnd, IDD_BACTIONT, "No Action"); } return TRUE; case WM_COMMAND: if ((wParam >= IDD_BTEXT) && (wParam <= IDD_BSPEC)) { if (IsDlgButtonChecked (hWnd, wParam) == 1) return 0; CheckRadioButton (hWnd, IDD_BTEXT, IDD_BSPEC, wParam); // Hide all type specific controls for (i = IDD_BITEMNAMET; i < IDD_BSPECTYPE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_HIDE); } switch (wParam) { // // Radio buttons // case IDD_BTEXT: ShowWindow (GetDlgItem (hWnd, IDD_BITEMNAMET), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_BITEMNAME), SW_SHOW); break; case IDD_BICON: ShowWindow (GetDlgItem (hWnd, IDD_BICONBOX), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_BICONPICT), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_BSETICON), SW_SHOW); break; case IDD_BSPEC: ShowWindow (GetDlgItem (hWnd, IDD_BSPECTYPET), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_BSPECTYPE), SW_SHOW); break; // // Icon Property Controls // case IDD_BICONPICT: // Delete old icon hIcon = (HICON)SendDlgItemMessage (hWnd, IDD_BICONPICT, STM_GETICON, 0, 0); if (hIcon) DestroyIcon (hIcon); hIcon = 0; hIcon = ExtractIcon (hInst, lpBarItem->szIconFName, lpBarItem->wIconIndex); if (hIcon < 2) { hIcon = LoadIcon (hInst, "WBIcon1"); GetModuleFileName (hInst, lpBarItem->szIconFName, sizeof (lpBarItem->szIconFName)); lpBarItem->wIconIndex = 1; } SendDlgItemMessage (hWnd, IDD_BICONPICT, STM_SETICON, hIcon, 0); return TRUE; case IDD_BSETICON: // Set up dummy PROG structure to fool SetIcon dialog Prog.szCmd[0] = '\0'; Prog.szDir[0] = '\0'; lstrcpy (Prog.szIconFName, lpBarItem->szIconFName); Prog.wIconIndex = lpBarItem->wIconIndex; // Edit icon selection hEdit = MyDisplayDialog(hInst, "SetIconBox", hWnd, (DLGPROC) SetIconDlgProc, (LPARAM)(LPGITEMDATA)&Prog); if (hEdit) { lpProg = (LPGITEMDATA)GlobalLock (hEdit); lstrcpy (lpBarItem->szIconFName, lpProg->szIconFName); lpBarItem->wIconIndex = lpProg->wIconIndex; GlobalUnlock (hEdit); GlobalFree (hEdit); // Force icon set PostMessage (hWnd, WM_COMMAND, IDD_BICONPICT, 0); } break; case IDD_BEDIT: // Edit entry with dialog { EDITITEM ei; ei.lParam = (LPARAM)lpItem; ei.sMode = 0; hEdit = MyDisplayDialog(hInst, "EditItem", hWnd, (DLGPROC) EditItemDlgProc, (LPARAM)(LPEDITITEM)&ei); } if (hEdit) { lpEdit = GlobalLock (hEdit); if (lpEdit) { // Skip past name lpEdit += lstrlen (lpEdit) + 1; // Get size of item sCnt = IncItemPtr (lpEdit, FALSE) - lpEdit; _fmemmove ((LPSTR)lpBarItem + sizeof (BARITEMDATA), lpEdit, sCnt); lpProg = (LPGITEMDATA)((LPSTR)lpBarItem + sizeof (BARITEMDATA)); switch (lpProg->sType) { case MTYPE_SUBMENU: SetDlgItemText (hWnd, IDD_BACTIONT, "Display Menu"); break; case MTYPE_PROG: SetDlgItemText (hWnd, IDD_BACTIONT, "Launch Program"); break; case MTYPE_WINLIST: SetDlgItemText (hWnd, IDD_BACTIONT, "Display Window List"); break; case MTYPE_CPL: SetDlgItemText (hWnd, IDD_BACTIONT, "Open Control Panel Applet"); break; case MTYPE_INTERNAL: SetDlgItemText (hWnd, IDD_BACTIONT, "WinBar Command"); break; default: SetDlgItemText (hWnd, IDD_BACTIONT, "No Action"); } } } break; // // Dialog box exit (OK and Cancel) // case IDOK: rc = 0; hEdit = GlobalAlloc (GHND, 128 + sizeof (BARITEMDATA) + sizeof (GITEMDATA)); lpEdit = GlobalLock (hEdit); if (lpEdit) { LPBARITEMDATA lpNewBar; LPSTR lpPtr; GetDlgItemText (hWnd, IDD_BITEMNAME, lpEdit, 128); lpNewBar = (LPBARITEMDATA) (lpEdit + lstrlen (lpEdit) + 1); lpNewBar->sType = MTYPE_BARITEM; // Retain icon info even if not icon. lstrcpy (lpNewBar->szIconFName, lpBarItem->szIconFName); lpNewBar->wIconIndex = lpBarItem->wIconIndex; // See which item type has been selected for (i = IDD_BTEXT; i < IDD_BSPEC+1; i++) if (IsDlgButtonChecked (hWnd, i) == 1) break; // Switch on item type selected switch (i) { case IDD_BTEXT: lpNewBar->sDisplayMode = DISP_TEXT; break; case IDD_BICON: lpNewBar->sDisplayMode = DISP_ICON; break; case IDD_BSPEC: sCnt = (INT)SendDlgItemMessage (hWnd, IDD_BSPECTYPE, CB_GETCURSEL, 0, 0); if (sCnt == CB_ERR) rc = ERR_NOINTSPECIFIED; else lpNewBar->sDisplayMode = DispTypes[sCnt].sMode; break; default: rc = 1000; break; } lpPtr = (LPSTR)lpBarItem + sizeof (BARITEMDATA); sCnt = IncItemPtr (lpPtr, FALSE) - lpPtr; _fmemmove ((LPSTR)lpNewBar + sizeof (BARITEMDATA), lpPtr, sCnt); GlobalUnlock (hEdit); } else rc = ERR_NOMEMORY; if (rc) { PrintError (hWnd, rc); GlobalFree (hEdit); return TRUE; } GlobalUnlock (hItem); GlobalFree (hItem); EndDialog(hWnd, hEdit); break; case IDCANCEL: GlobalUnlock (hItem); GlobalFree (hItem); EndDialog(hWnd, 0); break; } return TRUE; } return FALSE; } //============================================================ // EditItemDlgProc - Item Edit dialog box dialog procedure //============================================================ BOOL CALLBACK EditItemDlgProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { static char *szFilter[] = {"Programs", "*.EXE;*.COM;*.PIF;*.BAT", "All Files (*.*)", "*.*", "" }; char szStr[128], szTemp[128]; WNDPROC lpfnOldEditWndProc; LPSTR pszStr; INT i, j, rc, sCnt, sLen; INT sMode; LPGITEMDATA lpProg; GITEMDATA Prog; HGLOBAL hSubMem, hEdit, hTemp; LPSTR lpSub, lpSub1, lpEdit, lpEnd; HICON hIcon; HWND hCtl; switch (wMsg) { case WM_INITDIALOG: rc = 1; // This dlgproc is used for editing general items as well as // items in the startup group. If editing startup, don't // init controls that don't exist for that dialog. if (lParam) { sMode = ((LPEDITITEM)lParam)->sMode; lParam = ((LPEDITITEM)lParam)->lParam; // If editing startup item, hide icon ctls that are // normally hidden by sheet change code. if (sMode == 2) { ShowWindow (GetDlgItem (hWnd, IDD_ICONFNAME), SW_HIDE); ShowWindow (GetDlgItem (hWnd, IDD_ICONINDEX), SW_HIDE); } } else sMode = 0; SetProp (hWnd, MAKELP (0,aMode), sMode); SetProp (hWnd, MAKELP (0,aSubMenu), 0); SetProp (hWnd, MAKELP (0,aChanged), 0); // Set tab stops for submenu list i = 80; SendDlgItemMessage (hWnd, IDD_LIST, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&i); // Only init these controls if they exist switch (sMode) { case 0: // Default to normal launch for program CheckRadioButton (hWnd, IDD_RF1, IDD_RF3, IDD_RF1); // Fill in entries for special cmd list for (i = 0; i < dim (IntCmds); i++) { SendDlgItemMessage (hWnd, IDD_SPECTYPE, CB_ADDSTRING, 0, (LPARAM)(LPSTR)IntCmds[i].szName); } SendDlgItemMessage (hWnd, IDD_SPECTYPE, CB_SETCURSEL, 0, 0); // Fill in control panel applet list. if (hCPLData == 0) { HCURSOR hOldC; hOldC = SetCursor (LoadCursor (NULL, IDC_WAIT)); GetWindowText (GetParent (hWnd), szStr, sizeof (szStr)); SetWindowText (GetParent (hWnd), "Scanning control panel applets..."); hCPLData = GetCPLInfo(hMain); SetWindowText (GetParent (hWnd), szStr); SetCursor (hOldC); } lpSub = GlobalLock (hCPLData); if (lpSub) { sCnt = *((LPWORD)lpSub)++; for (i = 0; i < sCnt; i++) { lstrcpy (szStr, lpSub); // Remove underscore char from name StripAmpersand (szStr); SendDlgItemMessage (hWnd, IDD_CPLTYPE, CB_ADDSTRING, 0, (LPARAM)(LPSTR)szStr); lpSub += lstrlen (lpSub) + 1; lpSub += sizeof (CPLITEMDATA); } GlobalUnlock (hCPLData); } SendDlgItemMessage (hWnd, IDD_CPLTYPE, CB_SETCURSEL, 0, 0); // Hide all property controls for (i = IDD_LISTT; i < IDD_SPECTYPE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_HIDE); SendDlgItemMessage (hWnd, IDD_LIST, LB_SETCURSEL, 0, 0); // No break here, fall though to next case // case 2 is editing a startup item. This is limited to // programs only. case 2: // Subclass hotkey entry field edit box. Put the old edit proc in // the user dword of the window structure so that the subclassed // edit box can find it. Bad hack... only one subclassed win per // dialog. lpfnOldEditWndProc = MySubClassWindow (GetDlgItem (hWnd, IDD_HOTKEY), lpfnHKeyFieldProc); SetWindowLong (hWnd, DWL_USER, (LONG)lpfnOldEditWndProc); break; // case 1 is editing the startup group. This is limited to // a menu edit only. case 1: // If editing startup group, the window needs to be // positioned away from the winbar window which // is at the bottom of the screen. SetWindowPos (hWnd, NULL, 100, 100, 0, 0, SWP_NOSIZE | SWP_NOZORDER); break; } SetPasteButton (hWnd, IDD_PASTE, sMode); // Activate proper menu type controls if (lParam) { SetDlgItemText (hWnd, IDD_ITEMNAME, (LPSTR)lParam); lParam = (LPARAM) lParam + lstrlen ((LPSTR)lParam) + 1; // Adjust if bar item being edited if (*(LPWORD)lParam == MTYPE_BARITEM) { ShowWindow (GetDlgItem (hWnd, IDD_ITEMNAMET), SW_HIDE); ShowWindow (GetDlgItem (hWnd, IDD_ITEMNAME), SW_HIDE); SetWindowText (hWnd, "Edit Action"); SetDlgItemText (hWnd, IDD_ITEMNAME, "a"); lParam += sizeof (BARITEMDATA); SetFocus (GetDlgItem (hWnd, IDD_LIST)); rc = 0; } switch (*(LPWORD)lParam) { case MTYPE_SUBMENU: // Get handle to memory blk containing menu desc hSubMem = ((LPSUBMENUDATA)lParam)->hGlobal; if (hSubMem) { SetProp (hWnd, MAKELP (0, aSubMenu), hSubMem); // Fill the listbox FillSubmenuBox (hWnd, hSubMem, IDD_LIST); // Resize blk to allow for editing hTemp = GlobalReAlloc (hSubMem, 0x10000, GMEM_ZEROINIT); if (hTemp) hSubMem = hTemp; else { MessageBox (NULL, "Not enough memory", szTitleText, MB_OK | MB_ICONSTOP); EndDialog (hWnd, 0); } } SetFocus (GetDlgItem (hWnd, IDD_LIST)); PostMessage (hWnd, WM_COMMAND, IDD_TMENU, 0); break; case MTYPE_PROG: lpProg = (LPGITEMDATA)lParam; SetDlgItemText (hWnd, IDD_CMD, lpProg->szCmd); SetDlgItemText (hWnd, IDD_WDIR, lpProg->szDir); SetDlgItemText (hWnd, IDD_HOTKEY, DispHKeyText (lpProg->wHotKey, szStr, sizeof (szStr))); SetDlgItemText (hWnd, IDD_ICONFNAME, lpProg->szIconFName); SetDlgItemInt (hWnd, IDD_ICONINDEX, lpProg->wIconIndex, FALSE); // Set hotkey text if (lpProg->wHotKey) SendDlgItemMessage (hWnd, IDD_HOTKEY, WM_USER+101, lpProg->wHotKey, 0); // Set show buttons if (lpProg->wStartFlags == SW_SHOWMAXIMIZED) CheckRadioButton (hWnd, IDD_RF1, IDD_RF3, IDD_RF3); else if (lpProg->wStartFlags == SW_SHOWMINIMIZED) CheckRadioButton (hWnd, IDD_RF1, IDD_RF3, IDD_RF2); else CheckRadioButton (hWnd, IDD_RF1, IDD_RF3, IDD_RF1); PostMessage (hWnd, WM_COMMAND, IDD_TPROG, 0); break; case MTYPE_CPL: lpSub = GlobalLock (hCPLData); if (lpSub) { sCnt = *((LPWORD)lpSub)++; for (i = 0; i < sCnt; i++) { lpSub += lstrlen (lpSub) + 1; if (lstrcmp (((LPCPLITEMDATA)lpSub)->szCmd, ((LPCPLITEMDATA)lParam)->szCmd) == 0) break; lpSub += sizeof (CPLITEMDATA); } GlobalUnlock (hCPLData); } if (i < sCnt) SendDlgItemMessage (hWnd, IDD_CPLTYPE, CB_SETCURSEL, i, 0); PostMessage (hWnd, WM_COMMAND, IDD_TCPL, 0); break; case MTYPE_WINLIST: case MTYPE_SEP: case MTYPE_FIELD: case MTYPE_INTERNAL: switch (*(LPWORD)lParam) { case MTYPE_WINLIST: j = -1; break; case MTYPE_SEP: j = -2; break; case MTYPE_FIELD: j = -3; break; default: j = ((LPINTITEMDATA)lParam)->wID; } for (i = 0; i < dim (IntCmds); i++) { if (IntCmds[i].wID == (UINT)j) break; } SendDlgItemMessage (hWnd, IDD_SPECTYPE, CB_SETCURSEL, i, 0); PostMessage (hWnd, WM_COMMAND, IDD_TSPEC, 0); break; } } else { SetWindowText (hWnd, "Add Item"); PostMessage (hWnd, WM_COMMAND, IDD_TPROG, 0); } return rc; case WM_COMMAND: // Only do if these controls if they exist sMode = GetProp (hWnd, MAKELP (0, aMode)); if (sMode == 0) { if ((wParam >= IDD_TMENU) && (wParam <= IDD_TSPEC)) { if (IsDlgButtonChecked (hWnd, wParam) == 1) return 0; CheckRadioButton (hWnd, IDD_TMENU, IDD_TSPEC, wParam); // Hide all property controls for (i = IDD_LISTT; i < IDD_SPECTYPE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_HIDE); } } switch (wParam) { // // Radio buttons // case IDD_RF1: case IDD_RF2: case IDD_RF3: CheckRadioButton (hWnd, IDD_RF1, IDD_RF3, wParam); break; case IDD_TMENU: for (i = IDD_LISTT; i < IDD_PASTE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_SHOW); break; case IDD_TPROG: for (i = IDD_CMDT; i < IDD_BROWSE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_SHOW); // Force icon set PostMessage (hWnd, WM_COMMAND, IDD_ICONPICT, 0); // Force icon set and edit bat button enable PostMessage (hWnd, WM_COMMAND, IDD_CMD, MAKELPARAM (0, EN_KILLFOCUS)); break; case IDD_TCPL: for (i = IDD_CPLTYPET; i < IDD_CPLTYPE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_SHOW); break; case IDD_TSPEC: for (i = IDD_SPECTYPET; i < IDD_SPECTYPE+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_SHOW); break; // // Submenu Property Controls // case IDD_LIST: if (HIWORD (lParam) != LBN_DBLCLK) break; PostMessage (hWnd, WM_COMMAND, IDD_EDIT, MAKELPARAM (0, BN_CLICKED)); break; case IDD_ADD: hSubMem = (HGLOBAL)GetProp (hWnd, MAKELP (0, aSubMenu)); if (hSubMem == 0) { hSubMem = GlobalAlloc (GHND, 0x10000); if (hSubMem == 0) { MessageBox (hWnd, "No memory available", "Error", MB_OK | MB_ICONSTOP); break; } lpSub = GlobalLock (hSubMem); *((LPWORD)lpSub) = 0; SetProp (hWnd, MAKELP (0, aSubMenu), hSubMem); GlobalUnlock (hSubMem); } // Process add request i = AddEditItem (hWnd, hSubMem, IDD_LIST, TRUE, sMode); if (i) { if (i != ERR_CANCELED) PrintError (hWnd, i); } else SetProp (hWnd, MAKELP (0, aChanged), 1); break; case IDD_EDIT: if (((sMode == 0) && (IsDlgButtonChecked (hWnd, IDD_TPROG) == 1)) || (sMode == 2)) { PostMessage (hWnd, WM_COMMAND, IDD_EDITBAT, 0); break; } hSubMem = (HGLOBAL)GetProp (hWnd, MAKELP (0, aSubMenu)); if (hSubMem == 0) break; i = AddEditItem (hWnd, hSubMem, IDD_LIST, FALSE, sMode); if (i) { if (i != ERR_CANCELED) PrintError (hWnd, i); } else SetProp (hWnd, MAKELP (0, aChanged), 1); // Enable Paste button if clipboard format available SetPasteButton (hWnd, IDD_PASTE, 0); break; case IDD_CUT: case IDD_COPY: hSubMem = (HGLOBAL)GetProp (hWnd, MAKELP (0, aSubMenu)); if (hSubMem == 0) break; if (wParam == IDD_CUT) i = CutCopyItem (hWnd, hSubMem, IDD_LIST, TRUE); else i = CutCopyItem (hWnd, hSubMem, IDD_LIST, FALSE); if (i) { if (i != ERR_CANCELED) PrintError (hWnd, i); } else if (wParam == IDD_CUT) SetProp (hWnd, MAKELP (0, aChanged), 1); // Enable Paste button if clipboard format available sMode = GetProp (hWnd, MAKELP (0, aMode)); SetPasteButton (hWnd, IDD_PASTE, sMode); return TRUE; case IDD_PASTE: hSubMem = (HGLOBAL)GetProp (hWnd, MAKELP (0, aSubMenu)); if (hSubMem == 0) { hSubMem = GlobalAlloc (GHND, 0x10000); if (hSubMem == 0) { MessageBox (hWnd, "No memory available", "Error", MB_OK | MB_ICONSTOP); break; } lpSub = GlobalLock (hSubMem); *((LPWORD)lpSub) = 0; SetProp (hWnd, MAKELP (0, aSubMenu), hSubMem); GlobalUnlock (hSubMem); } i = PasteItem (hWnd, hSubMem, IDD_LIST, FALSE); if (i) PrintError (hWnd, i); else SetProp (hWnd, MAKELP (0, aChanged), 1); return TRUE; // // Program Property Controls // case IDD_CMD: if (HIWORD (lParam) == EN_KILLFOCUS) { //See if cmd an editable prog file GetDlgItemText (hWnd, IDD_CMD, szStr, sizeof (szStr)); i = GetEditFile (szStr); if (i == -1) EnableWindow (GetDlgItem (hWnd, IDD_EDITBAT), FALSE); else EnableWindow (GetDlgItem (hWnd, IDD_EDITBAT), TRUE); // Force icon set PostMessage (hWnd, WM_COMMAND, IDD_ICONPICT, 0); } break; case IDD_BROWSE: if (MyGetFilename (hWnd, szStr, sizeof (szStr), *szFilter, 1) == 0) break; SetDlgItemText (hWnd, IDD_CMD, szStr); pszStr = strrchr (szStr, '\\'); if (pszStr) { *pszStr = '\0'; SetDlgItemText (hWnd, IDD_WDIR, szStr); } else SetDlgItemText (hWnd, IDD_WDIR, ""); //See if cmd an editable prog file GetDlgItemText (hWnd, IDD_CMD, szStr, sizeof (szStr)); i = GetEditFile (szStr); if (i == -1) EnableWindow (GetDlgItem (hWnd, IDD_EDITBAT), FALSE); else EnableWindow (GetDlgItem (hWnd, IDD_EDITBAT), TRUE); PostMessage (hWnd, WM_COMMAND, IDD_ICONPICT, 0); break; case IDD_EDITBAT: GetDlgItemText (hWnd, IDD_CMD, szStr, sizeof (szStr)); i = GetEditFile (szStr); if (i != -1) { lstrcpy (szStr, BatEditors[i].szCmd); lstrcat (szStr, " "); GetDlgItemText (hWnd, IDD_CMD, szStr + lstrlen (szStr), sizeof (szStr) - lstrlen (szStr)); WinExec (szStr, SW_NORMAL); } break; case IDD_ICONPICT: // Delete old icon hIcon = (HICON)SendDlgItemMessage (hWnd, IDD_ICONPICT, STM_GETICON, 0, 0); if (hIcon) DestroyIcon (hIcon); hIcon = 0; // Try getting icon from icon file otherwise, use exe GetDlgItemText (hWnd, IDD_CMD, Prog.szCmd, sizeof (Prog.szCmd)); GetDlgItemText (hWnd, IDD_WDIR, Prog.szDir, sizeof (Prog.szDir)); GetDlgItemText (hWnd, IDD_ICONFNAME, Prog.szIconFName, sizeof (Prog.szIconFName)); Prog.wIconIndex = GetDlgItemInt (hWnd, IDD_ICONINDEX, &j, FALSE); hIcon = GetBestIcon (&Prog, 0); if (hIcon < 2) hIcon = ExtractIcon (hInst, "ProgMan.EXE", Prog.wIconIndex); if (hIcon > 1) SendDlgItemMessage (hWnd, IDD_ICONPICT, STM_SETICON, hIcon, 0); return TRUE; case IDD_SETICON: GetDlgItemText (hWnd, IDD_CMD, Prog.szCmd, sizeof (Prog.szCmd)); GetDlgItemText (hWnd, IDD_WDIR, Prog.szDir, sizeof (Prog.szDir)); GetDlgItemText (hWnd, IDD_ICONFNAME, Prog.szIconFName, sizeof (Prog.szIconFName)); Prog.wIconIndex = GetDlgItemInt (hWnd, IDD_ICONINDEX, &i, FALSE); // Edit icon selection hEdit = MyDisplayDialog(hInst, "SetIconBox", hWnd, (DLGPROC) SetIconDlgProc, (LPARAM)(LPGITEMDATA)&Prog); if (hEdit) { lpProg = (LPGITEMDATA)GlobalLock (hEdit); SetDlgItemText (hWnd, IDD_ICONFNAME, lpProg->szIconFName); SetDlgItemInt (hWnd, IDD_ICONINDEX, lpProg->wIconIndex, FALSE); GlobalUnlock (hEdit); GlobalFree (hEdit); // Force icon set PostMessage (hWnd, WM_COMMAND, IDD_ICONPICT, 0); } break; // // Dialog box exit (OK and Cancel) // case IDOK: rc = 0; hEdit = GlobalAlloc (GHND, 128 + sizeof (GITEMDATA)); lpEdit = GlobalLock (hEdit); GetDlgItemText (hWnd, IDD_ITEMNAME, lpEdit, 128); lpSub1 = lpEdit + lstrlen (lpEdit) + 1; hSubMem = (HGLOBAL)GetProp (hWnd, MAKELP (0, aSubMenu)); // If editing a startup item or the startup // group, default the radio button pick since // these ctls don't exist in the startup dlg // templates. switch (sMode) { case 0: // See which item type has been selected for (i = IDD_TMENU; i < IDD_TSPEC+1; i++) if (IsDlgButtonChecked (hWnd, i) == 1) break; break; case 1: i = IDD_TMENU; break; case 2: i = IDD_TPROG; break; } // Switch on item type selected switch (i) { case IDD_TMENU: if ((lstrlen (lpEdit) == 0) && (sMode == 0)) rc = ERR_NOMENUNAME; else if (hSubMem == 0) rc = ERR_EMPTYSUMMENU; else { *((LPWORD)lpSub1)++ = MTYPE_SUBMENU; // Resize menu block to min necessary for data lpSub = GlobalLock (hSubMem); sCnt = *(LPWORD)lpSub; lpEnd = lpSub + 2; for (i = 0; i < sCnt; i++) lpEnd = IncItemPtr (lpEnd, TRUE); GlobalUnlock (hSubMem); //zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz //why isn't the new handle of the realloced block stored in //the ptr to the submenu ? //zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz *(LPWORD)lpSub1 = hSubMem; hTemp = GlobalReAlloc (hSubMem, lpEnd - lpSub, 0); if (hTemp) *(LPWORD)lpSub1 = hTemp; //Zero mem handle so blk not deleted. hSubMem = 0; } break; case IDD_TPROG: if (lstrlen (lpEdit) == 0) { rc = ERR_NOMENUNAME; break; } *(LPWORD)lpSub1 = MTYPE_PROG; lpProg = (LPGITEMDATA)lpSub1; //Get and validate the working directory GetDlgItemText (hWnd, IDD_WDIR, lpProg->szDir, sizeof (lpProg->szDir)); if (lstrlen (lpProg->szDir) != 0) { lstrcpy (szTemp, lpProg->szDir); getcwd (szStr, sizeof (szStr)); i = chdir (szTemp); chdir (szStr); if (i != 0) { lstrcpy (szStr, "Can not locate the working directory:\n\n"); lstrcat (szStr, lpProg->szDir); lstrcat (szStr, "\n\nShould this directory be used anyway?"); i = MessageBox (hWnd, szStr, szAppName, MB_ICONEXCLAMATION | MB_YESNO); if (i != IDYES) return TRUE; } } //Get and validate the command line GetDlgItemText (hWnd, IDD_CMD, lpProg->szCmd, sizeof (lpProg->szCmd)); if (lstrlen (lpProg->szCmd) == 0) rc = ERR_NOCMDSPECIFIED; else { // Verify that program exists // First, strip off any cmd line params pszStr = lpProg->szCmd; while (*pszStr > ' ') pszStr++; if (pszStr) *pszStr = '\0'; // Call Shell.dll to get association ? i = (INT)FindExecutable (lpProg->szCmd, lpProg->szDir, szStr); if (i <= 32) { PrintError (hWnd, i + ERR_LAUNCH); return TRUE; } GetDlgItemText (hWnd, IDD_CMD, lpProg->szCmd, sizeof (lpProg->szCmd)); } // Get hot key lpProg->wHotKey = (UINT)SendDlgItemMessage (hWnd, IDD_HOTKEY, WM_USER+100, 0, 0); // Get icon file name and index GetDlgItemText (hWnd, IDD_ICONFNAME, lpProg->szIconFName, sizeof (lpProg->szIconFName)); lpProg->wIconIndex = GetDlgItemInt (hWnd, IDD_ICONINDEX, &i, FALSE); // Get startup state if (IsDlgButtonChecked (hWnd, IDD_RF2) == 1) lpProg->wStartFlags = SW_SHOWMINIMIZED; else if (IsDlgButtonChecked (hWnd, IDD_RF3) == 1) lpProg->wStartFlags = SW_SHOWMAXIMIZED; else lpProg->wStartFlags = SW_SHOWNORMAL; break; case IDD_TCPL: if (lstrlen (lpEdit) == 0) { rc = ERR_NOMENUNAME; break; } *(LPWORD)lpSub1 = MTYPE_CPL; sCnt = (INT)SendDlgItemMessage (hWnd, IDD_CPLTYPE, CB_GETCURSEL, 0, 0); if (sCnt == CB_ERR) rc = ERR_NOCPLSPECIFIED; else { lpSub = GlobalLock (hCPLData); // Scan cpl blk to get to entry selected sLen = *((LPINT)lpSub)++; if (sCnt >= sLen) sCnt = sLen - 1; for (i = 0; i < sCnt; i++) lpSub = IncItemPtr (lpSub, TRUE); // Skip past name lpSub += lstrlen (lpSub) + 1; // Copy command lstrcpy (((LPCPLITEMDATA)lpSub1)->szCmd, ((LPCPLITEMDATA)lpSub)->szCmd); } break; case IDD_TSPEC: sCnt = (INT)SendDlgItemMessage (hWnd, IDD_SPECTYPE, CB_GETCURSEL, 0, 0); if (sCnt == CB_ERR) rc = ERR_NOINTSPECIFIED; else { if ((INT)IntCmds[sCnt].wID > 0) { if (lstrlen (lpEdit) == 0) { rc = ERR_NOMENUNAME; break; } *(LPWORD)lpSub1 = MTYPE_INTERNAL; ((LPINTITEMDATA)lpSub1)->wID = IntCmds[sCnt].wID; } else if (IntCmds[sCnt].wID == -1) { if (lstrlen (lpEdit) == 0) { rc = ERR_NOMENUNAME; break; } *(LPWORD)lpSub1 = MTYPE_WINLIST; ((LPSUBMENUDATA)lpSub1)->hGlobal = hWinData; } else { *(LPWORD)lpSub1 = MTYPE_SEP; } } break; default: rc = 1000; break; } if (hSubMem) { GlobalUnlock (hSubMem); GlobalFree (hSubMem); } if (rc) { PrintError (hWnd, rc); GlobalUnlock (hEdit); GlobalFree (hEdit); return TRUE; } EndDialog(hWnd, hEdit); break; case IDCANCEL: rc = 0; if (GetProp (hWnd, MAKELP (0, aChanged))) { i = MessageBox (hWnd, "Discard Changes?",szAppName, MB_ICONQUESTION | MB_YESNOCANCEL); if (i == IDCANCEL) return TRUE; if (i == IDYES) rc = 1; } EndDialog(hWnd, rc); break; } return TRUE; case WM_DESTROY: RemoveProp (hWnd, MAKELP (0, aChanged)); RemoveProp (hWnd, MAKELP (0, aSubMenu)); sMode = RemoveProp (hWnd, MAKELP (0, aMode)); if (sMode != 1) { lpfnOldEditWndProc = (WNDPROC)GetWindowLong (hWnd, DWL_USER); MySubClassWindow (GetDlgItem (hWnd, IDD_HOTKEY), lpfnOldEditWndProc); } break; } return FALSE; } //------------------------------------------------------------ // GetEndofName - returns a pointer to the end of a filename //------------------------------------------------------------ LPSTR GetEndofName (LPSTR lpName) { char ch; while (*lpName) { ch = *lpName; if ((strchr (":\\.!#$%^&()-_{}~", ch) == 0) && !IsCharAlphaNumeric (*lpName)) break; lpName++; } return lpName; } //------------------------------------------------------------ // GetEditFile - returns a pointer to the name of an editor // for a file. //------------------------------------------------------------ INT GetEditFile (char *szStr) { INT i = -1; OFSTRUCT of; char *pszStr; i = -1; if (lstrlen (szStr)) { // Verify that program exists // First, strip off any cmd line params *GetEndofName (szStr) = '\0'; // Use OpenFile to parse filename OpenFile (szStr, &of, OF_PARSE); // Find extension pszStr = of.szPathName + lstrlen (of.szPathName); while (pszStr > of.szPathName) { if ((*pszStr == '.') || (*pszStr == '\\')) break; pszStr--; } // If ext, search edit prog list. if (*pszStr++ == '.') { for (i = 0; i < sBatEdCnt; i++) if (lstrcmp (pszStr, BatEditors[i].szExt) == 0) break; } if (i == sBatEdCnt) i = -1; } return i; } //------------------------------------------------------------ // Get best icon, returns an icon from icon file or program. //------------------------------------------------------------ HICON GetBestIcon (LPGITEMDATA lpProg, LPSTR lpName) { HICON hIcon; LPSTR lpFound; HINSTANCE hTest; char szStr[128]; char szResults[128]; hIcon = ExtractIcon (hInst, lpProg->szIconFName, lpProg->wIconIndex); // If no icon file, try program name if (hIcon < 2) { lstrcpy (szStr, lpProg->szCmd); *GetEndofName (szStr) = '\0'; hTest = FindExecutable (szStr, lpProg->szDir, szResults); hIcon = ExtractIcon (hInst, szResults, lpProg->wIconIndex); if (lpName) lpFound = szResults; } else lpFound = lpProg->szIconFName; if (lpName) lstrcpy (lpName, lpFound); return hIcon; } //------------------------------------------------------------ // ModIconList - Empty and fill icon listbox //------------------------------------------------------------ INT ModIconList (HWND hWnd, LPSTR szFile) { INT i, sCnt; HICON hIcon; HCURSOR hCursor; sCnt = (INT)SendDlgItemMessage (hWnd, IDD_LIST, LB_GETCOUNT, 0, 0); for (i = 0; i < sCnt; i++) { hIcon = (HICON)SendDlgItemMessage (hWnd, IDD_LIST, LB_GETITEMDATA, i, 0); DestroyIcon (hIcon); } SendDlgItemMessage (hWnd, IDD_LIST, LB_RESETCONTENT, 0, 0); sCnt = 0; if (szFile) { hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT)); hIcon = 2; for (i = 0; i < 256, hIcon > 1; i++) { hIcon = ExtractIcon (hInst, szFile, i); if (hIcon > 1) { SendDlgItemMessage (hWnd, IDD_LIST, LB_INSERTSTRING, i, (LPARAM)hIcon); sCnt++; } } SetCursor (hCursor); } SendDlgItemMessage (hWnd, IDD_LIST, WM_SETREDRAW, 1, 0); return sCnt; } //============================================================ // ListGroupDlgProc - List Groups dialog box dialog procedure //============================================================ BOOL CALLBACK ListGroupDlgProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { char szGFileName[128]; char szGroupName[192]; char szKey[32]; LPSTR lpEdit; HGLOBAL hEdit; HFILE hFile; OFSTRUCT of; GROUPHEADER gh; INT i, sLen; switch (wMsg) { case WM_INITDIALOG: // Set tab stops for submenu list i = 170; SendDlgItemMessage (hWnd, IDD_LIST, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&i); // Get title for each group for (i = 1; i < 41; i++) { wsprintf (szKey, "Group%d", i); GetPrivateProfileString ("Groups", szKey, "NOFILEHERE", szGFileName, sizeof (szGFileName), "progman.ini"); if (lstrcmp (szGFileName, "NOFILEHERE")) { // Open the group file hFile = OpenFile (szGFileName, &of, OF_READ | OF_SHARE_DENY_NONE); if (hFile != HFILE_ERROR) { if (_hread (hFile, &gh, sizeof (GROUPHEADER)) == sizeof (GROUPHEADER)) { // Get group name _llseek (hFile, gh.pName, 0); _hread (hFile, szGroupName, 64); szGroupName[63] = '\0'; lstrcat (szGroupName, "\t"); lstrcat (szGroupName, szGFileName); SendDlgItemMessage (hWnd, IDD_LIST, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szGroupName); } _lclose (hFile); } } } break; case WM_COMMAND: switch (wParam) { case IDD_LIST: if (HIWORD (lParam) != LBN_DBLCLK) break; PostMessage (hWnd, WM_COMMAND, IDOK, MAKELPARAM (0, BN_CLICKED)); break; case IDOK: i = (INT)SendDlgItemMessage (hWnd, IDD_LIST, LB_GETCURSEL, 0, 0); if (i == LB_ERR) EndDialog (hWnd, 0); SendDlgItemMessage (hWnd, IDD_LIST, LB_GETTEXT, i, (LPARAM)(LPSTR)szGroupName); sLen = lstrlen (szGroupName); for (i = 0; i < sLen; i++) if (szGroupName[i] == '\t') { i++; break; } hEdit = GlobalAlloc (GHND, 256); lpEdit = GlobalLock (hEdit); if (lpEdit) { lstrcpy (lpEdit, &szGroupName[i]); GlobalUnlock (hEdit); } else hEdit = 0; EndDialog (hWnd, hEdit); break; case IDCANCEL: EndDialog (hWnd, 0); break; } return TRUE; } return FALSE; } //============================================================ // SetIconDlgProc - SetIcon dialog box dialog procedure //============================================================ BOOL CALLBACK SetIconDlgProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { static char *szFilter[] = {"Icon Files", "*.ICO;*.EXE;*.DLL", "All Files (*.*)", "*.*", "" }; static sEdChange; char szStr[128]; LPGITEMDATA lpProg; INT i, sCnt, sSel; HGLOBAL hEdit; HICON hIcon; RECT rect; OFSTRUCT of; switch (wMsg) { case WM_INITDIALOG: SendDlgItemMessage (hWnd, IDD_LIST, LB_SETCOLUMNWIDTH, GetSystemMetrics (SM_CXICON)+8, 0); // Fill in combo box with possible icon files SendDlgItemMessage (hWnd, IDD_ILIBS, CB_RESETCONTENT, 0, 0); sCnt = 0; for (i = 0; i < sIconLibCnt; i++) { sSel = OpenFile (IconLibs[i].szName, &of, OF_EXIST); if (sSel != HFILE_ERROR) { SendDlgItemMessage (hWnd, IDD_CMD, CB_ADDSTRING, 0, (LPARAM)(LPSTR)of.szPathName); sCnt++; } } sEdChange = 0; if (lParam) { // See if program has an icon, if so, add it to the list lpProg = (LPGITEMDATA) lParam; hIcon = GetBestIcon (lpProg, szStr); if (hIcon > 1) { DestroyIcon (hIcon); // Make sure icon file not already listed if (SendDlgItemMessage (hWnd, IDD_CMD, CB_FINDSTRING, -1, (LPARAM)(LPSTR)szStr) == CB_ERR) { AnsiUpper (szStr); SendDlgItemMessage (hWnd, IDD_CMD, CB_INSERTSTRING, 0, (LPARAM)(LPSTR)szStr); sCnt++; } } } // Scan icon files to see if matching icon index can be loaded. sSel = -1; for (i = 0; i < sCnt; i++) { SendDlgItemMessage (hWnd, IDD_CMD, CB_GETLBTEXT, i, (LPARAM)(LPSTR)szStr); hIcon = ExtractIcon (hInst, szStr, lpProg->wIconIndex); if (hIcon > 1) { SendDlgItemMessage (hWnd, IDD_CMD, CB_SETCURSEL, i, 0); sSel = lpProg->wIconIndex; DestroyIcon (hIcon); break; } } // if matching icon index not found, select first icon of any file if ((i == sCnt) && (lpProg->wIconIndex)) { lpProg->wIconIndex = 0; for (i = 0; i < sCnt; i++) { SendDlgItemMessage (hWnd, IDD_CMD, CB_GETLBTEXT, i, (LPARAM)(LPSTR)szStr); hIcon = ExtractIcon (hInst, szStr, lpProg->wIconIndex); if (hIcon > 1) { SendDlgItemMessage (hWnd, IDD_CMD, CB_SETCURSEL, i, 0); sSel = lpProg->wIconIndex; DestroyIcon (hIcon); break; } } } // Fill the icon listbox i = (INT)SendDlgItemMessage (hWnd, IDD_CMD, CB_GETCURSEL, 0, 0); SendDlgItemMessage (hWnd, IDD_CMD, CB_GETLBTEXT, i, (LPARAM)(LPSTR)szStr); sCnt = ModIconList (hWnd, szStr); if (sSel != -1) SendDlgItemMessage (hWnd, IDD_LIST, LB_SETCURSEL, sSel, 0); else if (sCnt) SendDlgItemMessage (hWnd, IDD_LIST, LB_SETCURSEL, 0, 0); // Set the size of the listbox to match the size of icons GetClientRect (GetDlgItem (hWnd, IDD_LIST), &rect); SetWindowPos (GetDlgItem (hWnd, IDD_LIST), NULL, 0, 0, rect.right - rect.left, GetSystemMetrics (SM_CYICON) + GetSystemMetrics (SM_CYHSCROLL) + 8, SWP_NOZORDER | SWP_NOMOVE); return TRUE; case WM_MEASUREITEM: ((LPMEASUREITEMSTRUCT)lParam)->itemWidth = GetSystemMetrics (SM_CXICON) + 8; ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = GetSystemMetrics (SM_CYICON) + 8; return TRUE; case WM_DRAWITEM: { LPDRAWITEMSTRUCT di; HBRUSH hBrush; INT sOld; di = (LPDRAWITEMSTRUCT)lParam; if (di->itemState & ODS_SELECTED) { hBrush = CreateSolidBrush (GetSysColor (COLOR_HIGHLIGHT)); } else { hBrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW)); } FillRect (di->hDC, &di->rcItem, hBrush); DeleteObject (hBrush); sOld = SetMapMode (di->hDC, MM_TEXT); i = DrawIcon (di->hDC, di->rcItem.left+4, di->rcItem.top+4, (HICON)di->itemData); SetMapMode (di->hDC, sOld); } return TRUE; case WM_COMMAND: switch (wParam) { case IDD_CMD: if (HIWORD (lParam) == CBN_KILLFOCUS) { if (sEdChange) { SendDlgItemMessage (hWnd, IDD_CMD, WM_GETTEXT, sizeof (szStr), (LPARAM)(LPSTR)szStr); // Fill the icon listbox sCnt = ModIconList (hWnd, szStr); sEdChange = 0; i = 0; if (sCnt) i = (INT)SendDlgItemMessage (hWnd, IDD_CMD, CB_FINDSTRING, -1, (LPARAM)(LPSTR)szStr); if (i == CB_ERR) { AnsiUpper (szStr); i = (INT)SendDlgItemMessage (hWnd, IDD_CMD, CB_INSERTSTRING, 0, (LPARAM)(LPSTR)szStr); } SendDlgItemMessage (hWnd, IDD_LIST, LB_SETCURSEL, 0, 0); } } else if (HIWORD (lParam) == CBN_SELCHANGE) { i = (INT)SendDlgItemMessage (hWnd, IDD_CMD, CB_GETCURSEL, 0, 0); SendDlgItemMessage (hWnd, IDD_CMD, CB_GETLBTEXT, i, (LPARAM)(LPSTR)szStr); // Fill the icon listbox sCnt = ModIconList (hWnd, szStr); sEdChange = 0; SendDlgItemMessage (hWnd, IDD_LIST, LB_SETCURSEL, 0, 0); } else if (HIWORD (lParam) == CBN_EDITUPDATE) { sEdChange = 1; } break; case IDD_LIST: if (HIWORD (lParam) != LBN_DBLCLK) break; PostMessage (hWnd, WM_COMMAND, IDOK, MAKELPARAM (0, BN_CLICKED)); break; case IDD_BROWSE: if (MyGetFilename (hWnd, szStr, sizeof (szStr), *szFilter, 1) == 0) break; // Make sure icon file not already listed i = (INT) SendDlgItemMessage (hWnd, IDD_CMD, CB_FINDSTRING, -1, (LPARAM)(LPSTR)szStr); if (i == CB_ERR) { AnsiUpper (szStr); i = (INT)SendDlgItemMessage (hWnd, IDD_CMD, CB_INSERTSTRING, 0, (LPARAM)(LPSTR)szStr); } SendDlgItemMessage (hWnd, IDD_CMD, CB_SETCURSEL, i, 0); PostMessage (hWnd, WM_COMMAND, IDD_CMD, MAKELPARAM (0,CBN_SELCHANGE)); break; case IDOK: hEdit = GlobalAlloc (GHND, sizeof (GITEMDATA)); lpProg = (LPGITEMDATA)GlobalLock (hEdit); //Get and validate the working directory GetDlgItemText (hWnd, IDD_CMD, lpProg->szIconFName, sizeof (lpProg->szIconFName)); // Get hot key lpProg->wIconIndex = (UINT)SendDlgItemMessage (hWnd, IDD_LIST, LB_GETCURSEL, 0, 0); if (lpProg->wIconIndex == LB_ERR) lpProg->wIconIndex = 0; GlobalUnlock (hEdit); // Delete icons from listbox ModIconList (hWnd, 0); EndDialog(hWnd, hEdit); break; case IDCANCEL: ModIconList (hWnd, 0); EndDialog(hWnd, 0); break; } return TRUE; } return FALSE; } //============================================================ // RunDlgProc - Run dialog box dialog procedure //============================================================ BOOL CALLBACK RunDlgProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { static char *szFilter[] = {"Programs", "*.EXE;*.COM;*.PIF;*.BAT", "All Files (*.*)", "*.*", "" }; char szStr[128]; char *pTemp; LPGITEMDATA lpProg; HGLOBAL hEdit; LPSTR lpPtr; INT i; switch (wMsg) { case WM_INITDIALOG: // Fill in combo box with possible icon files SendDlgItemMessage (hWnd, IDD_ILIBS, CB_RESETCONTENT, 0, 0); pTemp = pStack; while (*pTemp) { SendDlgItemMessage (hWnd, IDD_CMD, CB_ADDSTRING, 0, (LPARAM)(LPSTR)pTemp); pTemp += lstrlen (pTemp) + 1; } if (lParam) { ; } CheckRadioButton (hWnd, IDD_RF1, IDD_RF3, IDD_RF1); return TRUE; case WM_COMMAND: switch (wParam) { // // Radio buttons // case IDD_RF1: case IDD_RF2: case IDD_RF3: CheckRadioButton (hWnd, IDD_RF1, IDD_RF3, wParam); break; case IDD_CMD: break; case IDD_BROWSE: if (MyGetFilename (hWnd, szStr, sizeof (szStr), *szFilter, 1) == 0) break; i = (INT) SendDlgItemMessage (hWnd, IDD_CMD, CB_FINDSTRING, -1, (LPARAM)(LPSTR)szStr); if (i == CB_ERR) i = (INT)SendDlgItemMessage (hWnd, IDD_CMD, CB_INSERTSTRING, 0, (LPARAM)(LPSTR)szStr); SendDlgItemMessage (hWnd, IDD_CMD, CB_SETCURSEL, i, 0); break; case IDOK: // Save command in stack pTemp = pStack; i = 0; SendDlgItemMessage (hWnd, IDD_CMD, WM_GETTEXT, sizeof (szStr), (LPARAM)(LPSTR)szStr); while ((pTemp + lstrlen (szStr) + 2 - pStack) < CMDSTACKSIZE) { lstrcpy (pTemp, szStr); if (lstrlen (pTemp)) pTemp += lstrlen (pTemp) + 1; if (SendDlgItemMessage (hWnd, IDD_CMD, CB_GETLBTEXT, i, (LPARAM)(LPSTR)szStr) == CB_ERR) break; i++; } pTemp += lstrlen (pTemp) + 1; *pTemp = '\0'; // Fill in result structure hEdit = GlobalAlloc (GHND, 128 + sizeof (GITEMDATA)); lpPtr = GlobalLock (hEdit); *lpPtr++ = '\0'; lpProg = (LPGITEMDATA)lpPtr; lpProg->sType = MTYPE_PROG; lstrcpy (lpProg->szCmd, pStack); lpProg->szDir[0] = '\0'; lpProg->szIconFName[0] = '\0'; lpProg->wIconIndex = 0; lpProg->wHotKey = 0; // Get startup state if (IsDlgButtonChecked (hWnd, IDD_RF2) == 1) lpProg->wStartFlags = SW_SHOWMINIMIZED; else if (IsDlgButtonChecked (hWnd, IDD_RF3) == 1) lpProg->wStartFlags = SW_SHOWMAXIMIZED; else lpProg->wStartFlags = SW_SHOWNORMAL; GlobalUnlock (hEdit); EndDialog(hWnd, hEdit); break; case IDCANCEL: EndDialog(hWnd, 0); break; } return TRUE; } return FALSE; } //============================================================ // FindDlgProc - Find dialog box dialog procedure //============================================================ BOOL CALLBACK FindDlgProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { /* static BOOL fAdv; INT i, rc, sState, sLen; char szText[80]; RECT rect; HWND hCtl; HGLOBAL hEdit; switch (wMsg) { case WM_INITDIALOG: fAdv = TRUE; // Fill in search area combo box DlgDirListComboBox (hWnd, "*.*", IDD_DOMAIN, IDD_TEXTSPEC, DDL_DRIVES); SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_INSERTSTRING, 0, (LPARAM)(LPSTR)"All Drives"); SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_SETCURSEL, 0, 0); // Fill in entries for size specs for (i = 0; i < dim (SizeSpecs); i++) SendDlgItemMessage (hWnd, IDD_SIZESPEC1, CB_ADDSTRING, 0, (LPARAM)(LPSTR)SizeSpecs[i].szText); SendDlgItemMessage (hWnd, IDD_SIZESPEC1, CB_SETCURSEL, 0, 0); // Fill in entries for Date specs for (i = 0; i < dim (DateSpecs); i++) SendDlgItemMessage (hWnd, IDD_DATESPEC1, CB_ADDSTRING, 0, (LPARAM)(LPSTR)DateSpecs[i].szText); SendDlgItemMessage (hWnd, IDD_DATESPEC1, CB_SETCURSEL, 0, 0); // Disable all type specific controls for (i = IDD_TYPEA; i < IDD_ATTRHIDDEN+1; i++) if (hCtl = GetDlgItem (hWnd, i)) EnableWindow (hCtl, FALSE); EnableWindow (GetDlgItem (hWnd, IDD_TYPEA), TRUE); CheckDlgButton (hWnd, IDD_TYPEA, 1); EnableWindow (GetDlgItem (hWnd, IDD_SIZEA), TRUE); CheckDlgButton (hWnd, IDD_SIZEA, 1); EnableWindow (GetDlgItem (hWnd, IDD_DATEA), TRUE); CheckDlgButton (hWnd, IDD_DATEA, 1); EnableWindow (GetDlgItem (hWnd, IDD_ATTRA), TRUE); CheckDlgButton (hWnd, IDD_ATTRA, 1); PostMessage (hWnd, WM_COMMAND, IDD_RBTYPE, 0); PostMessage (hWnd, WM_COMMAND, IDD_MORE, 0); return TRUE; case WM_COMMAND: // // Perf default action for radio buttons // if ((wParam >= IDD_RBTYPE) && (wParam <= IDD_RBATTR)) { if (IsDlgButtonChecked (hWnd, wParam) == 1) return 0; CheckRadioButton (hWnd, IDD_RBTYPE, IDD_RBATTR, wParam); // Hide all type specific controls for (i = IDD_TYPEA; i < IDD_ATTRHIDDEN+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_HIDE); } // // Perf default action for check boxes // if (((wParam == IDD_TYPEA) || (wParam == IDD_SIZEA) || (wParam == IDD_DATEA) || (wParam == IDD_ATTRA)) && (HIWORD (lParam) == BN_CLICKED)) { if (IsDlgButtonChecked (hWnd, wParam) == 1) sState = 0; else sState = 1; CheckDlgButton (hWnd, wParam, sState); // Enable/Disable associated ctls for (i = 1; i < 6; i++) if (hCtl = GetDlgItem (hWnd, wParam + i)) EnableWindow (hCtl, !sState); } switch (wParam) { // // Radio buttons // case IDD_RBTYPE: ShowWindow (GetDlgItem (hWnd, IDD_TYPEA), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_TYPESPECT), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_TYPESPEC), SW_SHOW); break; case IDD_RBSIZE: ShowWindow (GetDlgItem (hWnd, IDD_SIZEA), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_SIZESPECT), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_SIZESPEC), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_SIZESPEC1), SW_SHOW); break; case IDD_RBDATE: ShowWindow (GetDlgItem (hWnd, IDD_DATEA), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_DATESPECT), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_DATESPEC), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_DATESPEC1), SW_SHOW); break; case IDD_RBATTR: ShowWindow (GetDlgItem (hWnd, IDD_ATTRA), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_ATTRRONLY), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_ATTRARCH), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_ATTRSYSTEM), SW_SHOW); ShowWindow (GetDlgItem (hWnd, IDD_ATTRHIDDEN), SW_SHOW); break; // // Other controls // case IDD_MORE: // Get details of control sizes GetClientRect (GetDlgItem (hWnd, IDD_CONDITIONS), &rect); sLen = rect.bottom - rect.top + 5; GetWindowRect (GetDlgItem (hWnd, IDD_OUTLIST), &rect); rect.right -= rect.left; rect.bottom -= rect.top + 1; ScreenToClient (hWnd, (LPPOINT)&rect); if (fAdv) { // Hide all advanced controls for (i = IDD_CONDITIONS; i < IDD_ATTRHIDDEN+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_HIDE); // Resize list box SetWindowPos (GetDlgItem (hWnd, IDD_OUTLIST), NULL, rect.left, rect.top - sLen, rect.right, rect.bottom + sLen, SWP_NOZORDER); SetDlgItemText (hWnd, IDD_MORE, "Advanced ->"); } else { // Resize list box SetWindowPos (GetDlgItem (hWnd, IDD_OUTLIST), NULL, rect.left, rect.top + sLen, rect.right, rect.bottom - sLen, SWP_NOZORDER); // Show all advanced controls for (i = IDD_CONDITIONS; i < IDD_PROPS+1; i++) if (hCtl = GetDlgItem (hWnd, i)) ShowWindow (hCtl, SW_SHOW); for (i = IDD_RBTYPE; i <= IDD_RBATTR; i++) if (IsDlgButtonChecked (hWnd, i) == 1) { CheckDlgButton (hWnd, i, 0); PostMessage (hWnd, WM_COMMAND, i, MAKELPARAM (0, BN_CLICKED)); break; } SetDlgItemText (hWnd, IDD_MORE, "<- Simple"); } fAdv = !fAdv; break; case IDD_DOMAIN: if (HIWORD (lParam) != CBN_SELCHANGE) break; i = DlgDirSelectComboBoxEx (hWnd, szText, sizeof (szText), IDD_DOMAIN); //wsprintf (szDebug, "%d dir--:", i); //OutputDebugString (szDebug); //OutputDebugString (szText); //OutputDebugString ("\n"); if (i) { DlgDirListComboBox (hWnd, szText, IDD_DOMAIN, IDD_TEXTSPEC, DDL_DIRECTORY | DDL_EXCLUSIVE); // If root dir, add .. to go up to system GetDlgItemText (hWnd, IDD_TEXTSPEC, szText, sizeof (szText)); if (lstrcmp (&szText[1], ":\\") == 0) SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_INSERTSTRING, 0, (LPARAM)(LPSTR)"-Drives-"); } else { DlgDirListComboBox (hWnd, "*.*", IDD_DOMAIN, IDD_TEXTSPEC, DDL_DRIVES); lstrcpy (szText, "All Drives"); SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_INSERTSTRING, 0, (LPARAM)(LPSTR)szText); } GetDlgItemText (hWnd, IDD_TEXTSPEC, szText, sizeof (szText)); i = (INT) SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_ADDSTRING, 0, (LPARAM)(LPSTR)szText); SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_SETCURSEL, i, 0); SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_SETEDITSEL, 0, MAKELPARAM (0, 0)); // SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_DELETESTRING, // 0, (LPARAM)(LPSTR)szText); SetWindowText (hWnd, szText); hCtl = GetWindow (GetDlgItem (hWnd, IDD_DOMAIN), GW_CHILD); //wsprintf (szDebug, "Win %x\n", hCtl); //OutputDebugString (szDebug); // SetWindowText (hCtl, szText); // SetDlgItemText (hWnd, IDD_DOMAIN, szText); // i = (INT) SendDlgItemMessage (hWnd, IDD_DOMAIN, // CB_GETCURSEL, 0, 0); // SendDlgItemMessage (hWnd, IDD_DOMAIN, CB_GETLBTEXT, i, // (LPARAM)(LPSTR)szText); break; // // Dialog box exit (OK and Cancel) // case IDOK: rc = 0; // hEdit = GlobalAlloc (GHND, 128 + sizeof (BARITEMDATA) + // sizeof (GITEMDATA)); // lpEdit = GlobalLock (hEdit); // if (lpEdit) { // GlobalUnlock (hEdit); // } else // rc = ERR_NOMEMORY; EndDialog(hWnd, hEdit); break; case IDCANCEL: EndDialog(hWnd, 0); break; } return TRUE; } */ return FALSE; } //------------------------------------------------------------ // Draw3DRect - Routine that draws a 3D effect rectangle //------------------------------------------------------------ void LoadRect (HDC hdc, HPEN hDPen, HPEN hLPen, RECT *rect, INT sIn) { HPEN hOldPen; hOldPen = SelectObject (hdc, hDPen); //Start at bottom left, draw dark pen over and up. MoveTo (hdc, rect->left + sIn, rect->bottom - sIn); LineTo (hdc, rect->right - sIn, rect->bottom - sIn); LineTo (hdc, rect->right - sIn, rect->top + sIn); SelectObject (hdc, hLPen); //Start at bottom left, draw light pen up and over top. MoveTo (hdc, rect->left + sIn, rect->bottom - sIn); LineTo (hdc, rect->left + sIn, rect->top + sIn); LineTo (hdc, rect->right - sIn, rect->top + sIn); SelectObject (hdc, hOldPen); } //------------------------------------------------------------ // MakeFont - Quick and dirty font maker //------------------------------------------------------------ HFONT MakeFont (HDC hdc, char *pszFace, INT pt, INT sWeight, INT fItal) { LOGFONT lf; lf.lfHeight = -MulDiv(pt, GetDeviceCaps(hdc, LOGPIXELSY), 72); lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = sWeight; lf.lfItalic = (BYTE)fItal; lf.lfUnderline = 0; lf.lfStrikeOut = 0; lf.lfCharSet = ANSI_CHARSET; lf.lfOutPrecision = OUT_STROKE_PRECIS; lf.lfClipPrecision = CLIP_STROKE_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS; lstrcpy (lf.lfFaceName, pszFace); return CreateFontIndirect (&lf); } //------------------------------------------------------------ // LoadWndProc - Callback function for "loading..." window //------------------------------------------------------------ LONG CALLBACK LoadWndProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { char szText[80]; static HWND hStatWnd; static HWND hCprWnd; static BOOL fAboutBox; static HBRUSH hBrBack; HPEN hDPen, hLPen, hOldPen; PAINTSTRUCT ps; HFONT hFont, hOldFont; INT i, xPos, yPos, sLen; RECT rect; HDC hdc; switch (wMsg) { case WM_CREATE: if (((LPCREATESTRUCT) lParam)->lpCreateParams) fAboutBox = TRUE; else fAboutBox = FALSE; szText[0] = '\0'; xPos = GetSystemMetrics (SM_CXSCREEN) / 2; yPos = GetSystemMetrics (SM_CYSCREEN) / 2; GetWindowRect (hWnd, &rect); hCprWnd = CreateWindow ("static", "", WS_CHILD | WS_VISIBLE | SS_CENTER, (rect.right - rect.left - 250) / 2, 110, 250, 65, hWnd, 1, hInst, 0); hStatWnd = CreateWindow ("static", "Loading...", WS_CHILD | WS_VISIBLE | SS_CENTER, (rect.right - rect.left - 250) / 2, 180, 250, 35, hWnd, 1, hInst, 0); SetWindowText (hCprWnd, "Copyright \251 1995\n"\ "Ziff-Davis Publishing Company\n"\ "Written expressly for PC Magazine\n"\ "by Douglas Boling"); if (fAboutBox) { hdc = GetWindowDC (hWnd); SetMapMode (hdc, MM_TEXT); hFont = MakeFont (hdc, "Arial", 8, FW_BOLD, 0); ReleaseDC (hWnd, hdc); SendMessage (hStatWnd, WM_SETFONT, hFont, 0); SetWindowPos (hCprWnd, 0, (rect.right - rect.left - 250) / 2, 80, 0, 0, SWP_NOZORDER | SWP_NOSIZE); SetWindowPos (hStatWnd, 0, (rect.right - rect.left - 250) / 2, 155, 250, 60, SWP_NOZORDER); } xPos = max (0, xPos - (rect.right - rect.left)/2); yPos = max (0, yPos - (rect.bottom - rect.top)/2); SetWindowPos (hWnd, 0, xPos, yPos, 300, 225, SWP_NOZORDER); hBrBack = CreateSolidBrush (GetSysColor (COLOR_BTNFACE)); ShowWindow (hWnd, SW_SHOW); break; case WM_ACTIVATE: // If we loose focus, get rid of window if ((fAboutBox) && (wParam == WA_INACTIVE)) PostMessage (hWnd, WM_CHAR, VK_RETURN, 0); break; case WM_LBUTTONDOWN: if (fAboutBox) DestroyWindow (hWnd); break; case WM_CHAR: if ((fAboutBox) && ((wParam == VK_RETURN) || (wParam == VK_ESCAPE))) DestroyWindow (hWnd); break; case WM_CTLCOLOR: SetBkColor ((HDC) wParam, GetSysColor (COLOR_BTNFACE)); return hBrBack; case WM_SETTEXT: SetWindowText (hStatWnd, (LPSTR)lParam); return 0; case WM_PAINT: hdc = BeginPaint (hWnd, &ps); SetMapMode (hdc, MM_TEXT); SetBkColor (hdc, GetSysColor (COLOR_BTNFACE)); //Bevel the edges of the window GetClientRect (hWnd, &rect); hDPen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNSHADOW)); hLPen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNHIGHLIGHT)); for (i = 0; i < 4; i++) LoadRect (hdc, hDPen, hLPen, &rect, i); DeleteObject (hDPen); DeleteObject (hLPen); // Create a font to determine size of things hFont = MakeFont (hdc, "Arial", 40, FW_BOLD, 1); if (hFont == 0) break; SetTextAlign (hdc, TA_BOTTOM); xPos = 55; if (fAboutBox) yPos = 80; else yPos = 100; SetTextColor (hdc, RGB (128, 0, 0)); hOldFont = SelectObject (hdc, hFont); ExtTextOut (hdc, xPos, yPos, 0, 0, "Win", 3, 0); xPos += GetTextExtent (hdc, "Win", 3); SelectObject (hdc, hOldFont); DeleteObject (hFont); yPos -= 12; hFont = MakeFont (hdc, "Arial", 30, FW_BOLD, 0); if (hFont == 0) break; SetTextColor (hdc, RGB (0, 0, 128)); hOldFont = SelectObject (hdc, hFont); sLen = LOWORD (GetTextExtent (hdc, "Bar", 3)); ExtTextOut (hdc, xPos, yPos, 0, 0, "Bar", 3, 0); SelectObject (hdc, hOldFont); DeleteObject (hFont); yPos -= 2; hLPen = CreatePen (PS_SOLID, 4, RGB (0, 0, 128)); hOldPen = SelectObject (hdc, hLPen); MoveTo (hdc, xPos, yPos); LineTo (hdc, xPos + sLen, yPos); SelectObject (hdc, hOldPen); DeleteObject (hLPen); // Write version number in top right corner hFont = MakeFont (hdc, "Arial", 8, FW_NORMAL, 0); if (hFont == 0) { MessageBeep (0); break; } hOldFont = SelectObject (hdc, hFont); SetTextColor (hdc, RGB (0, 0, 0)); SetRect (&rect, 200, 20, 290, 35); if (sVer % 10) wsprintf (szText, "Version %d.%02d", sVer / 100, sVer % 100); else { wsprintf (szText, "Version %d.%d", sVer / 100, (sVer % 100)/10); } { DWORD dwExt; dwExt = GetTextExtent (hdc, szText, lstrlen (szText)); rect.left = rect.right - LOWORD (dwExt); rect.bottom = rect.top + HIWORD (dwExt); } DrawText (hdc, szText, -1, &rect, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_NOCLIP); SelectObject (hdc, hOldFont); DeleteObject (hFont); EndPaint (hWnd, &ps); break; case WM_DESTROY: DeleteObject (hBrBack); break; } return DefWindowProc(hWnd, wMsg, wParam, lParam); } //------------------------------------------------------------ // SizeEntrySpace - Makes room in a menu list for an entry //------------------------------------------------------------ INT SizeEntrySpace (LPSTR lpEntry, INT sCnt, INT sGap) { LPSTR lpSrc, lpDest, lpNext; HGLOBAL hTemp; LPSTR lpTemp; INT i; if (sCnt <= 0) return 1; lpNext = IncItemPtr (lpEntry, TRUE); // If gap greater than size of entry, create larger gap if (sGap > lpNext - lpEntry) { // Create a temp buffer since there is no way to scan backwards hTemp = GlobalAlloc (GHND, 0x10000); if (hTemp == 0) return 0; lpTemp = GlobalLock (hTemp); lpSrc = lpNext; lpDest = lpTemp; // Move remainder of entries to temp buffer for (i = 0; i < sCnt; i++) { lpNext = IncItemPtr (lpSrc, TRUE); while (lpSrc < lpNext) *lpDest++ = *lpSrc++; } lpSrc = lpTemp; lpDest = lpEntry + sGap; // Move entries back to original buffer for (i = 0; i < sCnt; i++) { lpNext = IncItemPtr (lpSrc, TRUE); while (lpSrc < lpNext) *lpDest++ = *lpSrc++; } GlobalUnlock (hTemp); GlobalFree (hTemp); } else { // Gap less than size of entry, move entries down to fill in space lpDest = lpEntry + sGap; lpSrc = lpNext; for (i = 0; i < sCnt; i++) { lpNext = IncItemPtr (lpSrc, TRUE); while (lpSrc < lpNext) *lpDest++ = *lpSrc++; } } return 1; } //------------------------------------------------------------ // StripAmpersand - Removes & from strings //------------------------------------------------------------ void StripAmpersand (LPSTR szStr) { INT i, sLen; sLen = lstrlen (szStr); for (i = 0; i < sLen; i++) if (szStr[i] == '&') { lstrcpy (&szStr[i], &szStr[i+1]); break; } return; } //------------------------------------------------------------ // FillSubmenuBox - Fills submenu listbox //------------------------------------------------------------ INT FillSubmenuBox (HWND hWnd, HGLOBAL hSubMem, INT wID) { char szStr[128]; LPSTR lpSub; INT i, j, sCnt, sTop; sTop = (INT)SendDlgItemMessage (hWnd, wID, LB_GETTOPINDEX, 0, 0); SendDlgItemMessage (hWnd, wID, LB_RESETCONTENT, 0, 0); lpSub = GlobalLock (hSubMem); if (!lpSub) return 0; sCnt = *((LPWORD)lpSub)++; for (i = 0; i < sCnt; i++) { lstrcpy (szStr, lpSub); if (lstrlen (szStr) > 17) lstrcpy (&szStr[17], "..."); // Remove underscore char from name StripAmpersand (szStr); lpSub += lstrlen (lpSub) + 1; if (*(LPWORD)lpSub == MTYPE_BARITEM) { if (((LPBARITEMDATA)lpSub)->sDisplayMode == DISP_ICON) { lstrcpy (szStr, "Icon"); } else for (j = 0; j < dim (DispTypes); j++) { if (((LPBARITEMDATA)lpSub)->sDisplayMode == DispTypes[j].sMode) { lstrcpy (szStr, DispTypes[j].szName); break; } } lpSub += sizeof (BARITEMDATA); } lstrcat (szStr, "\t"); switch (*(LPWORD)lpSub) { case MTYPE_SUBMENU: lstrcat (szStr, "Submenu"); break; case MTYPE_PROG: lstrcat (szStr, "Program"); break; case MTYPE_CPL: lstrcat (szStr, "CPL Applet"); break; case MTYPE_WINLIST: lstrcat (szStr, "Window List"); break; case MTYPE_INTERNAL: lstrcat (szStr, "WinBar Cmd"); break; case MTYPE_SEP: lstrcat (szStr, "Separator"); break; case MTYPE_FIELD: lstrcat (szStr, "Field"); break; } lpSub = IncItemPtr (lpSub, FALSE); SendDlgItemMessage (hWnd, wID, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szStr); } GlobalUnlock (hSubMem); SendDlgItemMessage (hWnd, wID, LB_SETTOPINDEX, sTop, 0); SendDlgItemMessage (hWnd, wID, LB_SETCURSEL, sTop, 0); return 0; } //------------------------------------------------------------ // DispHKeyText - Converts a key value into text //------------------------------------------------------------ char *DispHKeyText (UINT wKey, char *pszOut, INT sOutMax) { UINT wFlags; sOutMax--; *pszOut = '\0'; if (sOutMax < 6) return pszOut; if (wKey & 0x400) { strcat (pszOut, "Alt + "); sOutMax -= 6; } if (sOutMax < 7) return pszOut; if (wKey & 0x200) { strcat (pszOut, "Ctrl + "); sOutMax -= 7; } if (sOutMax < 8) return pszOut; if (wKey & 0x100) { strcat (pszOut, "Shift + "); sOutMax -= 8; } if (wKey & 0x1000) wFlags = 0x300; else wFlags = 0x200; wKey &= 0xff; if (wKey) GetKeyNameText (MAKELONG (0, wFlags | MapVirtualKey(wKey, 0)), &pszOut[strlen (pszOut)], sOutMax); return pszOut; } //============================================================ // Hotkey edit box subclass procedure //============================================================ LONG CALLBACK HKeyFieldProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) { char szKeyText[50]; WNDPROC lpfnOldEditWndProc; static LONG lLastKey; static UINT wAddKey; switch (wMsg) { case WM_CREATE: wAddKey = 0; break; case WM_USER+100: return wAddKey; case WM_USER+101: wAddKey = wParam; SetWindowText (hWnd, DispHKeyText (wAddKey, szKeyText, sizeof (szKeyText))); return 0; case WM_KILLFOCUS: if (!(wAddKey & 0x00ff)) { wAddKey = 0; SetWindowText (hWnd, DispHKeyText (wAddKey, szKeyText, sizeof (szKeyText))); } break; case WM_SETFOCUS: lLastKey = 0; break; case WM_SYSKEYDOWN: if ((wParam == VK_TAB) || (wParam == VK_SPACE) || (wParam == VK_ESCAPE)) break; case WM_KEYDOWN: //Ignore repeat WM_KEYDOWN messages if (lParam == lLastKey) return 0; lLastKey = lParam; // Turn key state into text wAddKey = wParam; if ((wAddKey == VK_CONTROL) || (wAddKey == VK_MENU) || (wAddKey == VK_SHIFT)) wAddKey = 0; szKeyText[0] = '\0'; if (lParam & 0x20000000) wAddKey |= 0x400; if (GetKeyState (VK_CONTROL) & 0x8000) wAddKey |= 0x200; if (GetKeyState (VK_SHIFT) & 0x8000) wAddKey |= 0x100; // Hide extended key bit in VK word if (lParam & 0x1000000) wAddKey |= 0x1000; // If no shift used, don't allow if (!(wAddKey & 0x700)) { wAddKey = 0; } SetWindowText (hWnd, DispHKeyText (wAddKey, szKeyText, sizeof (szKeyText))); return 0; case WM_SYSKEYUP: case WM_SYSCHAR: if ((wParam == VK_TAB) || (wParam == VK_SPACE) || (wParam == VK_ESCAPE)) break; case WM_KEYUP: if (!(wAddKey & 0xff)) { wAddKey = 0; SetWindowText (hWnd, DispHKeyText (wAddKey, szKeyText, sizeof (szKeyText))); } case WM_CHAR: return 0; } // Kluge to get old edit proc necessary since edit item dialogs // are recursive. lpfnOldEditWndProc = (WNDPROC)GetWindowLong (GetParent (hWnd), DWL_USER); return CallWindowProc ((FARPROC)lpfnOldEditWndProc, hWnd, wMsg, wParam, lParam); } //------------------------------------------------------------ // WriteItemtoINI - Writes a menu to the INI file //------------------------------------------------------------ INT WriteItemtoINI (HGLOBAL hGroup, UINT *wItem, char *pszSecName) { LPWORD lpPtr; char szItem[40]; INT i, sCnt; if (hGroup == 0) return 0; lpPtr = (LPWORD) GlobalLock (hGroup); if (!lpPtr) return 0; sCnt = *lpPtr++; MyWritePrivateProfileInt (pszSecName, PRO_CNT, sCnt, szProfileName); if (sCnt) { for (i = 0; i < sCnt; i++) { wsprintf (szItem, "Item%d", *wItem); (*wItem)++; // Add item name to submenu list if (lstrlen ((LPBYTE)lpPtr)) WritePrivateProfileString (pszSecName, szItem, (LPSTR)lpPtr, szProfileName); else MyWritePrivateProfileInt (pszSecName, szItem, -1, szProfileName); // Move ptr past name lpPtr = (LPWORD)((LPBYTE)lpPtr + lstrlen ((LPBYTE)lpPtr) + 1); // Clear item section. Add section type WritePrivateProfileString (szItem, 0, 0, szProfileName); MyWritePrivateProfileInt (szItem, PRO_TYPE, *lpPtr, szProfileName); // If bar item, process now if (*lpPtr == MTYPE_BARITEM) { MyWritePrivateProfileInt (szItem, PRO_BDISPMODE, ((LPBARITEMDATA)lpPtr)->sDisplayMode, szProfileName); WritePrivateProfileString (szItem, PRO_BICONNAME, ((LPBARITEMDATA)lpPtr)->szIconFName, szProfileName); MyWritePrivateProfileInt (szItem, PRO_BICONINDEX, ((LPBARITEMDATA)lpPtr)->wIconIndex, szProfileName); lpPtr = (LPWORD)((LPBYTE)lpPtr + sizeof (BARITEMDATA)); } switch (*lpPtr) { case MTYPE_SUBMENU: WriteItemtoINI (((LPSUBMENUDATA)lpPtr)->hGlobal, wItem, szItem); break; case MTYPE_PROG: WritePrivateProfileString (szItem, PRO_CMD, ((LPGITEMDATA)lpPtr)->szCmd, szProfileName); WritePrivateProfileString (szItem, PRO_DIR, ((LPGITEMDATA)lpPtr)->szDir, szProfileName); WritePrivateProfileString (szItem, PRO_ICONNAME, ((LPGITEMDATA)lpPtr)->szIconFName, szProfileName); MyWritePrivateProfileInt (szItem, PRO_ICONINDEX, ((LPGITEMDATA)lpPtr)->wIconIndex, szProfileName); MyWritePrivateProfileInt (szItem, PRO_HOTKEY, ((LPGITEMDATA)lpPtr)->wHotKey, szProfileName); MyWritePrivateProfileInt (szItem, PRO_FLAGS, ((LPGITEMDATA)lpPtr)->wStartFlags, szProfileName); break; case MTYPE_CPL: WritePrivateProfileString (szItem, PRO_CMD, ((LPGITEMDATA)lpPtr)->szCmd, szProfileName); break; case MTYPE_INTERNAL: MyWritePrivateProfileInt (szItem, PRO_ID, ((LPINTITEMDATA)lpPtr)->wID, szProfileName); break; case MTYPE_WINLIST: case MTYPE_SEP: case MTYPE_WINITEM: case MTYPE_FIELD: break; default: MessageBeep(0); wsprintf (szDebug, "**** INISave -- Unknown item type %x****\n", *(LPWORD)lpPtr); OutputDebugString (szDebug); break; } lpPtr = (LPWORD) IncItemPtr ((LPSTR)lpPtr, FALSE); } } GlobalUnlock (hGroup); return 0; } //------------------------------------------------------------ // SavetoINI - Writes the data to the ini file. //------------------------------------------------------------ void SavetoINI (HGLOBAL hBar) { UINT i = 0; WriteItemtoINI (hBar, &i, PRO_MAINBAR); return; } //------------------------------------------------------------ // FreeMenuBlk - Traces though a chain of menu blocks and // frees the memory. //------------------------------------------------------------ INT FreeMenuBlk (HGLOBAL hIn) { LPBYTE lpPtr; INT i, sCnt; if (hIn == 0) return 0; lpPtr = GlobalLock (hIn); if (lpPtr == 0) { MessageBeep(0); OutputDebugString ("FreeMenuBlk --Bad memory segment.\n"); return 0; } sCnt = *((LPWORD)lpPtr)++; if (sCnt) { for (i = 0; i < sCnt; i++) { // Skip past name lpPtr += lstrlen (lpPtr) + 1; // If bar item, skip if (*(LPWORD)lpPtr == MTYPE_BARITEM) lpPtr += sizeof (BARITEMDATA); // If submenu, recurse if (*(LPWORD)lpPtr == MTYPE_SUBMENU) FreeMenuBlk (((LPSUBMENUDATA)lpPtr)->hGlobal); lpPtr = IncItemPtr (lpPtr, FALSE); } } GlobalUnlock (hIn); GlobalFree (hIn); return 0; } //------------------------------------------------------------ // WriteMenutoBlk - Writes a menu to a single blk of RAM // The memory check works as long as 2 bytes remain in out // buff when routine is called. This is true for recursive // calls because of size of submenudata structure. //------------------------------------------------------------ char huge *WriteMenutoBlk (HGLOBAL hGroup, HGLOBAL *hOut, char huge **hpStart, char huge *hpOut, LONG *plSize) { LPBYTE lpPtr; INT i, sCnt; if (hGroup == 0) return 0; lpPtr = GlobalLock (hGroup); if (lpPtr == 0) { MessageBeep(0); OutputDebugString ("WriteMenutoBlk --Bad memory segment.\n"); return 0; } sCnt = *((LPWORD)lpPtr)++; *((LPWORD)hpOut)++ = sCnt; if (sCnt) { for (i = 0; (i < sCnt) && hpOut; i++) { hpOut = WriteItemtoBlk (&lpPtr, hOut, hpStart, hpOut, plSize); } } GlobalUnlock (hGroup); return hpOut; } //------------------------------------------------------------ // WriteItemtoBlk - Writes a single menu item to the output // blk of RAM. If the item is a submenu, the routine // recurses to save the submenu items. //------------------------------------------------------------ char huge *WriteItemtoBlk (LPSTR *lpIn, HGLOBAL *hOut, char huge **hpStart, char huge *hpOut, LONG *plSize) { HGLOBAL hTemp; LPSTR lpPtr; LONG lBlkSize, lOffset; INT i, sLen; lpPtr = *lpIn; // Check to see if enough room in output blk sLen = IncItemPtr (lpPtr, TRUE) - lpPtr; if (*plSize < sLen) { lOffset = hpOut - *hpStart; GlobalUnlock (*hOut); lBlkSize = GlobalSize (*hOut); hTemp = GlobalReAlloc (*hOut, lBlkSize + 0x10000, 0); if (hTemp == 0) { return 0; } *hOut = hTemp; lBlkSize = GlobalSize (*hOut); *plSize = lBlkSize - lOffset; *hpStart = (char huge *)GlobalLock (*hOut); hpOut = *hpStart + lOffset; } // Sub size of item from blk size *plSize -= sLen; // Copy item name. Dealing with a huge blk here, don't lstrcpy while (*hpOut++ = *lpPtr++); // Recompute length without name sLen = IncItemPtr (lpPtr, FALSE) - lpPtr; // If bar item, copy now if (*(LPWORD)lpPtr == MTYPE_BARITEM) { for (i = 0; i < sizeof (BARITEMDATA); i++) *hpOut++ = *lpPtr++; sLen = IncItemPtr (lpPtr, FALSE) - lpPtr; } // If submenu, recurse if (*(LPWORD)lpPtr == MTYPE_SUBMENU) { // Copy submenu type *((LPWORD)hpOut)++ = *((LPWORD)lpPtr)++; hpOut = WriteMenutoBlk (*((LPWORD)lpPtr)++, hOut, hpStart, hpOut, plSize); if (hpOut == 0) return 0; } else { // For all but submenu, copy for (i = 0; i < sLen; i++) *hpOut++ = *lpPtr++; } *lpIn = lpPtr; return hpOut; } //------------------------------------------------------------ // SavetoMem - copy menu data to memory blk //------------------------------------------------------------ HGLOBAL SavetoMem (HGLOBAL hMenu) { HGLOBAL hOut; char huge *hpStart; char huge *hpOut; LONG lSize = 0x10000; // Allocate memory for output buffer hOut = GlobalAlloc (GHND, lSize); if (hOut == 0) return 0; hpStart = (char huge *) GlobalLock (hOut); if (hpStart == 0) return 0; hpOut = hpStart; hpOut = WriteMenutoBlk (hMenu, &hOut, &hpStart, hpOut, &lSize); // If successful, unlock if (hpOut) GlobalUnlock (hOut); else { GlobalFree (hOut); hOut = 0; } return hOut; } //------------------------------------------------------------ // SaveBartoMem - copy menu data to memory blk //------------------------------------------------------------ HGLOBAL SaveBartoMem (HGLOBAL hMenu, HGLOBAL hStartup, LONG *plSize) { HGLOBAL hOut; char huge *hpStart; char huge *hpOut; LONG lSize = 0x10000; // Allocate memory for output buffer hOut = GlobalAlloc (GHND, lSize); if (hOut == 0) return 0; hpStart = (char huge *) GlobalLock (hOut); if (hpStart == 0) return 0; hpOut = hpStart; // If memory allocated and locked, call recursive routine to // save startup group and bar config if (hStartup) hpOut = WriteMenutoBlk (hStartup, &hOut, &hpStart, hpOut, &lSize); else *((LPWORD)hpOut)++ = 0; if (hpOut) hpOut = WriteMenutoBlk (hMenu, &hOut, &hpStart, hpOut, &lSize); // If successful, unlock if (hpOut) { GlobalUnlock (hOut); if (plSize) *plSize = hpOut - hpStart; } else { GlobalFree (hOut); hOut = 0; } return hOut; } //------------------------------------------------------------ // SavetoClip - Saves a menu item to the clipboard //------------------------------------------------------------ INT SavetoClip (HWND hWnd, LPSTR lpPtr) { HGLOBAL hOut, hTemp; char huge *hpStart; char huge *hpOut; LONG lSize = 0x10000, lFSize; INT rc = 0; // Allocate memory for output buffer hOut = GlobalAlloc (GHND, lSize); if (hOut == 0) return 0; hpStart = (char huge *) GlobalLock (hOut); if (hpStart == 0) return 0; hpOut = hpStart; // If memory allocated and locked, call recursive routine if (hpOut) hpOut = WriteItemtoBlk (&lpPtr, &hOut, &hpStart, hpOut, &lSize); // If successful, unlock if (hpOut) { GlobalUnlock (hOut); lFSize = GlobalSize (hOut); hTemp = GlobalReAlloc (hOut, lFSize - lSize + 15, GMEM_ZEROINIT); if (hTemp) hOut = hTemp; if (OpenClipboard (hWnd)) { EmptyClipboard(); if (SetClipboardData (hWBClipFmt, hOut) == 0) { GlobalFree (hOut); rc = ERR_BADCLIPSET; } CloseClipboard(); } } else { GlobalFree (hOut); rc = ERR_NOMEMORY; } return rc; } //------------------------------------------------------------ // SaveINIData - Writes general config data to INI file //------------------------------------------------------------ INT SaveINIData (char *pszProfile) { INT i; char szKey[64]; MyWritePrivateProfileInt ("Editors", "Count", sBatEdCnt, pszProfile); // Save the list of batch editors for (i = 0; i < sBatEdCnt; i++) { wsprintf (szKey, "Ext%d", i); WritePrivateProfileString ("Editors", szKey, BatEditors[i].szExt, pszProfile); wsprintf (szKey, "Cmd%d", i); WritePrivateProfileString ("Editors", szKey, BatEditors[i].szCmd, pszProfile); } // Save the names of the default icon libraries MyWritePrivateProfileInt ("IconLibs", "Count", sIconLibCnt, pszProfile); // Get icon libraries for (i = 0; i < sIconLibCnt; i++) { wsprintf (szKey, "%d", i); WritePrivateProfileString ("IconLibs", szKey, IconLibs[i].szName, pszProfile); } return 0; } //------------------------------------------------------------ // GetINIData - Reads general config data from INI file //------------------------------------------------------------ INT GetINIData (char *pszProfile) { INT i; char szKey[64]; i = GetPrivateProfileInt ("Editors", "Count", -1, pszProfile); if (i > 0) { sBatEdCnt = i; sBatEdCnt = min (sBatEdCnt, dim (BatEditors)); // Get batch editors for (i = 0; i < sBatEdCnt; i++) { wsprintf (szKey, "Ext%d", i); GetPrivateProfileString ("Editors", szKey, "", BatEditors[i].szExt, sizeof (BatEditors[0].szExt), pszProfile); AnsiUpper (BatEditors[i].szExt); wsprintf (szKey, "Cmd%d", i); GetPrivateProfileString ("Editors", szKey, "", BatEditors[i].szCmd, sizeof (BatEditors[0].szCmd), pszProfile); } } // Get the names of the default icon libraries i = GetPrivateProfileInt ("Editors", "Count", -1, pszProfile); if (i > 0) { sIconLibCnt = i; sIconLibCnt = min (sIconLibCnt, dim (IconLibs)); // Get icon libraries for (i = 0; i < sIconLibCnt; i++) { wsprintf (szKey, "%d", i); GetPrivateProfileString ("IconLibs", szKey, "", IconLibs[i].szName, sizeof (IconLibs[0].szName), pszProfile); } } return 0; } //------------------------------------------------------------ // SavetoFile - Writes the data to the File file. //------------------------------------------------------------ INT SavetoFile (HGLOBAL hBar, HGLOBAL hStartup, HFONT hFont, UINT wHotKey, char *szOut) { HGLOBAL hOut; LONG lSize = 0, lWritten; char huge *hpOut; OFSTRUCT of; HFILE hFile; INT rc = 0; LOGFONT fm; hOut = SaveBartoMem (hBar, hStartup, &lSize); if (hOut) { hFile = OpenFile (szOut, &of, OF_CREATE | OF_READWRITE | OF_SHARE_EXCLUSIVE); if (hFile != HFILE_ERROR) { hpOut = GlobalLock (hOut); // Write identifer tag for file and write _lwrite (hFile, szFileTag, lstrlen (szFileTag) + 1); // Write status flags _lwrite (hFile, &fFlags, sizeof (UINT)); // Write hotkey _lwrite (hFile, &wHotKey, sizeof (UINT)); // Write current font if (GetObject (hFont, sizeof (fm), &fm) == 0) { hFont = GetStockObject (SYSTEM_FONT); GetObject (hFont, sizeof (fm), &fm); } _lwrite (hFile, &fm, sizeof (fm)); // Write size of menu data _lwrite (hFile, &lSize, sizeof (LONG)); // Write the menu data. lWritten = _hwrite (hFile, hpOut, lSize); if (lWritten != lSize) rc = ERR_DISKFULL; GlobalUnlock (hOut); _lclose (hFile); } else rc = ERR_DOS + of.nErrCode; GlobalFree (hOut); } return rc; } //------------------------------------------------------------ // RestoreItemfromMem - Create menu structure from memory blk //------------------------------------------------------------ LPSTR RestoreItemfromMem (char huge **hpIn, LPSTR lpPtr) { HGLOBAL hSubMenu; INT i, sLen; //wsprintf (szDebug, "Restoring item at %x:%x title:", // SELECTOROF(*hpIn), OFFSETOF(*hpIn)); //OutputDebugString (szDebug); //OutputDebugString (*hpIn); //OutputDebugString ("\n"); //MyYield(); // Copy item name. while (*lpPtr++ = *(*hpIn)++); // If bar item, copy now if (*(UINT huge *)*hpIn == MTYPE_BARITEM) { for (i = 0; i < sizeof (BARITEMDATA); i++) *lpPtr++ = *(*hpIn)++; } // If submenu, recurse if (*(UINT huge *)*hpIn == MTYPE_SUBMENU) { // Copy submenu type *((LPWORD)lpPtr)++ = *((UINT huge *)*hpIn)++; hSubMenu = RestoreMenufromMem (hpIn); if (hSubMenu == 0xffff) return 0; *((LPWORD)lpPtr)++ = hSubMenu; } else if (*(UINT huge *)*hpIn == MTYPE_WINLIST) { // Copy type *((LPWORD)lpPtr)++ = *((UINT huge *)*hpIn)++; *((LPWORD)lpPtr)++ = hWinData; *hpIn += 2; } else { // For all but submenu, copy sLen = (char huge *)IncItemPtr ((LPSTR)*hpIn, FALSE) - *hpIn; for (i = 0; i < sLen; i++) *lpPtr++ = *(*hpIn)++; } return lpPtr; } //------------------------------------------------------------ // RestoreMenufromMem - Create menu structure from memory blk //------------------------------------------------------------ HGLOBAL RestoreMenufromMem (char huge **hpIn) { HGLOBAL hMenu = 0, hSubMenu; LPSTR lpPtr, lpStart; INT i, sCnt; sCnt = *((UINT huge *)(*hpIn))++; //wsprintf (szDebug, "Restoring menu at %x:%x count: %d, title:", // SELECTOROF(*hpIn), OFFSETOF(*hpIn), sCnt); //OutputDebugString (szDebug); //OutputDebugString (*hpIn); //OutputDebugString ("\n"); //MyYield(); if (sCnt) { // Allocate memory for output buffer hMenu = GlobalAlloc (GHND, 0x10000); if (hMenu == 0) return 0xffff; lpPtr = GlobalLock (hMenu); if (lpPtr == 0) return 0xffff; lpStart = lpPtr; *((LPWORD)lpPtr)++ = sCnt; for (i = 0; (i < sCnt) && lpPtr; i++) { lpPtr = RestoreItemfromMem (hpIn, lpPtr); } GlobalUnlock (hMenu); if (!lpPtr) { GlobalFree (hMenu); return 0xffff; } hSubMenu = GlobalReAlloc (hMenu, lpPtr - lpStart, 0); if (hSubMenu) hMenu = hSubMenu; } return hMenu; } //------------------------------------------------------------ // ReadfromClip - Create item structure from the clipboard //------------------------------------------------------------ HGLOBAL ReadfromClip (HWND hWnd) { HGLOBAL hItem, hClip; char huge *hpClip; LPSTR lpPtr; // Read the data from the clipboard if (OpenClipboard (hWnd)) { if (IsClipboardFormatAvailable (hWBClipFmt) == 0) { CloseClipboard(); return 0; } hClip = GetClipboardData (hWBClipFmt); } else return 0; hpClip = (char huge *)GlobalLock (hClip); if (hpClip) { // Allocate memory for output buffer. Leave at least // this much size for working space needed by paste // routine. hItem = GlobalAlloc (GHND, 129 + sizeof (BARITEMDATA) + sizeof (GITEMDATA)); lpPtr = GlobalLock (hItem); if (lpPtr) { // Restore menu structure from huge memory blk lpPtr = RestoreItemfromMem (&hpClip, lpPtr); GlobalUnlock (hItem); if (lpPtr == 0) { GlobalFree (hItem); hItem = 0; } } else hItem = 0; GlobalUnlock (hClip); } else hItem = 0; CloseClipboard(); return hItem; } //------------------------------------------------------------ // ReadfromFile - Reads bar data from a file //------------------------------------------------------------ INT ReadfromFile (char *szIn, HGLOBAL *hBar, HGLOBAL *hStartup, LOGFONT *pfm, UINT *pwHotKey) { HGLOBAL hIn; LONG lSize, lRead; OFSTRUCT of; HFILE hFile; INT rc = 0; char huge *hpIn; char szTemp[128]; SetWindowText (hLoadWnd, "Reading saved configuration..."); MyYield(); if (lstrlen (szIn)) { hFile = OpenFile (szIn, &of, OF_READ | OF_SHARE_EXCLUSIVE); if (hFile != HFILE_ERROR) { // Read identifer tag _lread (hFile, szTemp, strlen (szFileTag) + 1); if (lstrcmp (szTemp, szFileTag)) { _lclose (hFile); return ERR_BADFILE; } // Get status flags _lread (hFile, &fFlags, sizeof (UINT)); // Get hotkey _lread (hFile, pwHotKey, sizeof (UINT)); // Get current font _lread (hFile, pfm, sizeof (LOGFONT)); // Get size of menu structure _lread (hFile, &lSize, sizeof (LONG)); hIn = GlobalAlloc (GHND, lSize); if (hIn == 0) { _lclose (hFile); return ERR_NOMEMORY; } hpIn = GlobalLock (hIn); // Read the menu data. lRead =_hread (hFile, hpIn, lSize); if (lRead != lSize) rc = ERR_BADFILE; _lclose (hFile); if (rc == 0) { *hStartup = RestoreMenufromMem (&hpIn); *hBar = RestoreMenufromMem (&hpIn); } GlobalUnlock (hIn); GlobalFree (hIn); } else rc = ERR_DOS + of.nErrCode; } else rc = ERR_BADFILE; return rc; } //------------------------------------------------------------ // GetGroupData - Reads information from a Group file //------------------------------------------------------------ HGLOBAL GetGroupData (char *pszName, char *pszGName) { HGLOBAL hGlobal, hFileMem, hTemp; LPSTR lpData, lpTemp, lpFile; LPSTR lpPtr, lpEnd; char szSwap[128]; LPGITEMDATA far *lpIndex; HFILE hFile; OFSTRUCT of; LONG lFileSize; INT i, sNum, sCnt = 0; LPITEMDATA lpItem; LPGITEMDATA lpGItem, lpGStart; hGlobal = GlobalAlloc (GHND, 0x10000); if (!hGlobal) return 0; lpData = GlobalLock (hGlobal); lpPtr = lpData; lpIndex = (LPGITEMDATA far *)(lpData + 0x10000 - 121 * sizeof (LPGITEMDATA)); hFileMem = GlobalAlloc (GHND, 0x10000); if (!hFileMem) { GlobalUnlock (hGlobal); return 0; } lpFile = GlobalLock (hFileMem); // Open the group file hFile = OpenFile (pszName, &of, OF_READ | OF_SHARE_DENY_NONE); if (hFile != HFILE_ERROR) { // Compute size of group file by seeking to end of file lFileSize = _llseek (hFile, 0, 2); _llseek (hFile, 0, 0); if (_hread (hFile, lpFile, lFileSize) == lFileSize) { // Copy group name lpTemp = lpFile + ((LPGROUPHEADER)lpFile)->pName; lstrcpy (pszGName, lpTemp); // Save number items in sub menu sNum = ((LPGROUPHEADER)lpFile)->cItems; if (sNum > 120) sNum = 120; lpPtr += 2; lpGStart = (LPGITEMDATA)lpPtr; lpGItem = lpGStart; // Scan group item structures to get names of each items. for (i = 0; i < sNum; i++) { if (((LPGROUPHEADER)lpFile)->rgiItems[i]) { lpItem = (LPITEMDATA)(lpFile + ((LPGROUPHEADER)lpFile)->rgiItems[i]); // Copy name lpTemp = lpFile + lpItem->pName; lstrcpy (lpPtr, lpTemp); lpGItem = (LPGITEMDATA)(lpPtr + lstrlen (lpPtr) + 1); *lpIndex++ = lpGItem; // Set menu item type lpGItem->sType = MTYPE_PROG; // Copy command, the path specified is actually the working dir lpTemp = lpFile + lpItem->pCommand; // Assume a path (working dir) exists lstrcpy (lpGItem->szDir, lpTemp); lpEnd = GetEndofName (lpGItem->szDir); while ((lpEnd > lpGItem->szDir) && (*lpEnd != '\\')) lpEnd--; // if path specified, its the working dir, so move cmd over if (lpEnd > lpGItem->szDir) { *lpEnd = '\0'; // Copy old path to dir field lstrcpy (lpGItem->szCmd, lpEnd+1); } else { // no working dir, so move cmd and zero wdir lstrcpy (lpGItem->szCmd, lpTemp); lpGItem->szDir[0] = '\0'; } // Copy Icon path and index number lpTemp = lpFile + lpItem->pIconPath; lstrcpy (lpGItem->szIconFName, lpTemp); lpGItem->wIconIndex = lpItem->iIcon; if ((lpGItem->wIconIndex) && (lstrlen (lpTemp) == 0)) lstrcpy (lpGItem->szIconFName, "PROGMAN.EXE"); // Assume nothing for tag items at this point lpGItem->wHotKey = 0; lpGItem->wStartFlags = SW_NORMAL; lpPtr = (LPSTR) (lpGItem + 1); sCnt++; } else *lpIndex++ = 0; } *((LPWORD)lpData) = sCnt; // Save ptr to end of data in segment. lpEnd = lpPtr; // Get ptr to tag structures lpPtr = lpFile + ((LPGROUPHEADER)lpFile)->cbGroup; lpIndex = (LPGITEMDATA far *)(lpData + 0x10000 - 121 * sizeof (LPGITEMDATA)); if (((LPTAGDATA)lpPtr)->wID == 0x8000) { while (((LPTAGDATA)lpPtr)->wID != 0xFFFF) { // Get ptr to item tag addressses lpGItem = *(lpIndex + ((LPTAGDATA)lpPtr)->wItem); if (lpGItem) { switch (((LPTAGDATA)lpPtr)->wID) { // Path tag case 0x8101: // Get ptr to path lpTemp = ((LPTAGDATA)lpPtr)->rgb; // Copy wdir (actually path) to temp string lstrcpy (szSwap, lpTemp); // Append cmd lstrcat (szSwap, lpGItem->szCmd); // Move back to cmd string lstrcpy (lpGItem->szCmd, szSwap); break; // Hot key tag case 0x8102: lpGItem->wHotKey = *(LPWORD)((LPTAGDATA)lpPtr)->rgb; break; // Start condition tag case 0x8103: lpGItem->wStartFlags = SW_SHOWMINIMIZED; break; } } lpPtr += ((LPTAGDATA)lpPtr)->cb; } } } _lclose (hFile); } GlobalUnlock (hFileMem); GlobalFree (hFileMem); GlobalUnlock (hGlobal); hTemp = GlobalReAlloc (hGlobal, lpEnd - lpData, 0); if (hTemp) hGlobal = hTemp; return hGlobal; } //------------------------------------------------------------ // GetGroupInfo - Reads the group file information //------------------------------------------------------------ HGLOBAL GetGroupInfo (LPSTR lpStartupName, HGLOBAL *hStartup) { HGLOBAL hGroupMenu, hGroup, hTemp; LPBYTE lpPtr; LPBYTE lpStart; char szGFileName[128]; char szGName[128]; char szKey[40]; char szStat[128]; INT i, sCnt = 0; *hStartup = 0; // Create Programs menu using Group information hGroupMenu = GlobalAlloc (GHND, 0x10000); if (!hGroupMenu) return 0; lpStart = GlobalLock (hGroupMenu); lpPtr = lpStart; lpPtr += 2; //Leave room for menu count // Find path to group by looking in ProgMan.ini for (i = 1; i < 51; i++) { wsprintf (szKey, "Group%d", i); GetPrivateProfileString ("Groups", szKey, "NOFILEHERE", szGFileName, sizeof (szGFileName), "progman.ini"); if (lstrcmp (szGFileName, "NOFILEHERE")) { // Get data for each item in group file hGroup = GetGroupData (szGFileName, szGName); lstrcpy (szStat, "Migrating group:\n"); lstrcat (szStat, szGName); lstrcat (szStat, "..."); SetWindowText (hLoadWnd, szStat); MyYield(); if (hGroup) { if (lstrcmpi (szGName, lpStartupName) == 0) *hStartup = hGroup; else { // Copy group name lstrcpy (lpPtr, szGName); lpPtr = lpPtr + lstrlen (lpPtr) + 1; // Save group memory handle *((LPWORD)lpPtr)++ = MTYPE_SUBMENU; *((LPWORD)lpPtr)++ = hGroup; GlobalUnlock (hGroup); sCnt++; } } } } *(LPWORD)lpStart = sCnt; GlobalUnlock (hGroupMenu); hTemp = GlobalReAlloc (hGroupMenu, lpPtr - lpStart, 0); if (hTemp) hGroupMenu = hTemp; return hGroupMenu; } //------------------------------------------------------------ // GetDefProgMenu - Creates the default Programs menu //------------------------------------------------------------ HGLOBAL GetDefProgMenu (HGLOBAL *hStartup) { HGLOBAL hProgMenu, hSettings, hTemp, hMainMenu; LPBYTE lpPtr, lpStart, lpProg, lpPS; INT sCnt = 0; char szStartTitle[40]; // Create Programs menu using Group information GetPrivateProfileString ("Settings", "Startup", "StartUp", szStartTitle, sizeof (szStartTitle), "ProgMan.INI"); hProgMenu = GetGroupInfo (szStartTitle, hStartup); // Create Main menu hMainMenu = GlobalAlloc (GHND, 0x4000); if (!hMainMenu) return 0; lpStart = GlobalLock (hMainMenu); lpPtr = lpStart; lpPtr += 2; sCnt = 0; // Add Programs submenu lstrcpy ((LPSTR)lpPtr, "&Groups"); lpPtr += lstrlen (lpPtr) + 1; *((LPWORD)lpPtr)++ = MTYPE_SUBMENU; *((LPWORD)lpPtr)++ = hProgMenu; sCnt++; // Create Settings submenu hSettings = GlobalAlloc (GHND, 0x4000); lpProg = GlobalLock (hSettings); lpPS = lpProg; *((LPWORD)lpProg)++ = 0; // Add configure Winbar item lstrcpy ((LPSTR)lpProg, "&Configure WinBar..."); lpProg += lstrlen (lpProg) + 1; *((LPWORD)lpProg)++ = MTYPE_INTERNAL; *((LPWORD)lpProg)++ = IDM_CONFIG; (*(LPWORD)lpPS)++; // Add edit startup group item lstrcpy ((LPSTR)lpProg, "Edit &StartUp Group..."); lpProg += lstrlen (lpProg) + 1; *((LPWORD)lpProg)++ = MTYPE_INTERNAL; *((LPWORD)lpProg)++ = IDM_EDITSTARTUP; (*(LPWORD)lpPS)++; // Add control panel submenu lstrcpy ((LPSTR)lpProg, "Control &Panel"); lpProg += lstrlen (lpProg) + 1; *((LPWORD)lpProg)++ = MTYPE_SUBMENU; *((LPWORD)lpProg)++ = hCPLData; (*(LPWORD)lpPS)++; GlobalUnlock (hSettings); hTemp = GlobalReAlloc (hSettings, lpProg - lpPS, 0); if (hTemp) hSettings = hTemp; // Add settings submenu to main menu lstrcpy (lpPtr, "&Settings"); lpPtr += lstrlen (lpPtr) + 1; *((LPWORD)lpPtr)++ = MTYPE_SUBMENU; *((LPWORD)lpPtr)++ = hSettings; sCnt++; // Add About menu item lstrcpy (lpPtr, "&About WinBar..."); lpPtr += lstrlen (lpPtr) + 1; ((LPINTITEMDATA)lpPtr)->sType = MTYPE_INTERNAL; ((LPINTITEMDATA)lpPtr)->wID = IDM_ABOUT; lpPtr += sizeof (INTITEMDATA); sCnt++; // Add Run menu item lstrcpy (lpPtr, "&Run..."); lpPtr += lstrlen (lpPtr) + 1; ((LPINTITEMDATA)lpPtr)->sType = MTYPE_INTERNAL; ((LPINTITEMDATA)lpPtr)->wID = IDM_RUN; lpPtr += sizeof (INTITEMDATA); sCnt++; // Add sep *lpPtr++ = 0; *((LPWORD)lpPtr)++ = MTYPE_SEP; sCnt++; // Add Exit menu lstrcpy (lpPtr, "E&xit"); lpPtr += lstrlen (lpPtr) + 1; ((LPINTITEMDATA)lpPtr)->sType = MTYPE_INTERNAL; ((LPINTITEMDATA)lpPtr)->wID = IDM_EXIT; lpPtr += sizeof (INTITEMDATA); sCnt++; *(LPWORD)lpStart = sCnt; GlobalUnlock (hMainMenu); hTemp = GlobalReAlloc (hMainMenu, lpPtr - lpStart, 0); if (hTemp) hMainMenu = hTemp; return hMainMenu; } //------------------------------------------------------------ // GetCPLLibInfo - Reads info from one library //------------------------------------------------------------ LPSTR GetCPLLibInfo (HWND hWnd, HINSTANCE hLib, char *pszName, LPSTR lpPtr, INT *psItems) { INT i, sCnt; CPIPROC far *lpCPIApplet; NEWCPLINFO nci; lpCPIApplet = (CPIPROC far *)GetProcAddress (hLib, "CPLApplet"); if (lpCPIApplet) { if ((*lpCPIApplet) (hWnd, CPL_INIT, 0, 0) == 0) return lpPtr; sCnt = (INT)(*lpCPIApplet) (hWnd, CPL_GETCOUNT, 0, 0); for (i = 0; i < sCnt; i++) { (*lpCPIApplet) (hWnd, CPL_NEWINQUIRE, i, (LPARAM)(LPVOID)&nci); lstrcpy (lpPtr, nci.szName); lpPtr += lstrlen (lpPtr) + 1; ((LPCPLITEMDATA)lpPtr)->sType = MTYPE_CPL; lstrcpy (((LPCPLITEMDATA)lpPtr)->szCmd, "CONTROL "); lstrcat (((LPCPLITEMDATA)lpPtr)->szCmd, pszName); lstrcat (((LPCPLITEMDATA)lpPtr)->szCmd, " "); // Remove any underscore char from name. StripAmpersand (nci.szName); lstrcat (((LPCPLITEMDATA)lpPtr)->szCmd, nci.szName); lpPtr += sizeof (CPLITEMDATA); (*psItems)++; // Send stop message (*lpCPIApplet) (hWnd, CPL_STOP, i, nci.lData); } // Send exit message (*lpCPIApplet) (hWnd, CPL_EXIT, 0, 0); } return lpPtr; } //------------------------------------------------------------ // GetCPLInfo - Reads the control panel applet data //------------------------------------------------------------ HGLOBAL GetCPLInfo (HWND hWnd) { HGLOBAL hGlobal, hTemp; INT i, rc, sCnt, sItems = 0; LPSTR lpPtr, lpStart; FIND_T fs; char szSysDir[128]; char szCPName[128]; HINSTANCE hLib; OFSTRUCT of; HWND hList; if (hLoadWnd) { SetWindowText (hLoadWnd, "Reading control panel information..."); MyYield(); } // Use hidden listbox to keep track of files containing applets. // It allocates its own memory, has a find function, and is fairly // easy to use. hList = CreateWindow ("listbox", "", LBS_NOREDRAW | WS_VISIBLE | WS_CHILD, 0, 0, 10, 10, hWnd, 1, hInst, 0); // First query applets listed in MMCPL seciton of CONTROL.INI hTemp = GlobalAlloc (GHND, 0x10000); lpStart = GlobalLock (hTemp); if (lpStart) { // Get list of keys in MMCPL section i = GetPrivateProfileString ("MMCPL", 0, "", lpStart, 0xffff, "CONTROL.INI"); lpPtr = lpStart; if (i) { while (*lpPtr) { // Get data for each key GetPrivateProfileString ("MMCPL", lpPtr, "", szCPName, sizeof (szCPName), "CONTROL.INI"); // See if we're talking about a file if (OpenFile (szCPName, &of, OF_EXIST) != HFILE_ERROR) SendMessage (hList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)of.szPathName); lpPtr += lstrlen (lpPtr) + 1; } } } GlobalUnlock (hTemp); GlobalFree (hTemp); // Get CPL files from the CONTROL.EXE dir // Find control.exe OpenFile ("CONTROL.EXE", &of, OF_PARSE); // Get only directory lpPtr = of.szPathName + lstrlen (of.szPathName); while (lpPtr > of.szPathName) { lpPtr--; if (*lpPtr == '\\') break; } lstrcpy (lpPtr+1, "*.CPL"); rc = _dos_findfirst (of.szPathName, _A_RDONLY | _A_ARCH, &fs); while (rc == 0) { if (SendMessage (hList, LB_FINDSTRING, -1, (LPARAM)(LPSTR)fs.name) == LB_ERR) SendMessage (hList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)fs.name); rc = _dos_findnext (&fs); } // Get CPL files from the system dir GetSystemDirectory (szSysDir, sizeof (szSysDir)); // If dir of control.exe different from sys dir, search it too lstrcpy (szCPName, szSysDir); lstrcat (szCPName, "\\*.CPL"); if (lstrcmpi (of.szPathName, szCPName)) { rc = _dos_findfirst (szCPName, _A_RDONLY | _A_ARCH, &fs); while (rc == 0) { if (SendMessage (hList, LB_FINDSTRING, -1, (LPARAM)(LPSTR)fs.name) == LB_ERR) SendMessage (hList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)fs.name); rc = _dos_findnext (&fs); } } // Now that we've collected the file names, open each and add to // a newly created menu structure. hGlobal = GlobalAlloc (GHND, 0x10000); if (!hGlobal) return 0; lpStart = GlobalLock (hGlobal); lpPtr = lpStart; lpPtr += 2; // Skip item count field // Now that we've collected the list, use it to query applets sCnt = (INT)SendMessage (hList, LB_GETCOUNT, 0, 0); for (i = 0; i < sCnt; i++) { SendMessage (hList, LB_GETTEXT, i, (LPARAM)(LPSTR)szCPName); hLib = LoadLibrary (szCPName); if (hLib > HINSTANCE_ERROR) { lpPtr = GetCPLLibInfo (hWnd, hLib, szCPName, lpPtr, &sItems); FreeLibrary (hLib); } } DestroyWindow (hList); //Thanks listbox *(LPWORD)lpStart = sItems; GlobalUnlock (hGlobal); hTemp = GlobalReAlloc (hGlobal, lpPtr - lpStart, 0); if (hTemp) hGlobal = hTemp; if (hLoadWnd) SetWindowText (hLoadWnd, ""); MyYield(); return hGlobal; } //------------------------------------------------------------ // GetDefaultBar - Creates a default bar configuration //------------------------------------------------------------ HLOCAL GetDefaultBar (HGLOBAL *hStartup, UINT *pfFlags) { HGLOBAL hGlobal, hTemp, hProgData; INT sItems = 0; LPSTR lpPtr, lpStart; LPBARITEMDATA lpBarPtr; // Default status flags *pfFlags |= FLAG_ASKONEXIT | FLAG_SAVEONEXIT | FLAG_ALWAYSONTOP; // Load data from group files and control panel. hProgData = GetDefProgMenu(hStartup); SetWindowText (hLoadWnd, "Creating default menus..."); MyYield(); hGlobal = GlobalAlloc (GHND, 0x1000); lpStart = (LPSTR)GlobalLock (hGlobal); lpPtr = lpStart + 2; // Skip item count field lstrcpy (lpPtr, "&Programs"); lpPtr += lstrlen (lpPtr) + 1; lpBarPtr = (LPBARITEMDATA) lpPtr; lpBarPtr->sType = MTYPE_BARITEM; lpBarPtr->sDisplayMode = DISP_TEXT; GetModuleFileName (hInst, lpBarPtr->szIconFName, sizeof (lpBarPtr->szIconFName)); lpBarPtr->wIconIndex = 1; lpPtr += sizeof (BARITEMDATA); *((LPWORD)lpPtr)++ = MTYPE_SUBMENU; *((LPWORD)lpPtr)++ = hProgData; sItems++; lstrcpy (lpPtr, "&Windows"); lpPtr += lstrlen (lpPtr) + 1; lpBarPtr = (LPBARITEMDATA) lpPtr; lpBarPtr->sType = MTYPE_BARITEM; lpBarPtr->sDisplayMode = DISP_TEXT; lpBarPtr->szIconFName[0] = '\0'; lpBarPtr->wIconIndex = -1; lpPtr += sizeof (BARITEMDATA); *((LPWORD)lpPtr)++ = MTYPE_WINLIST; *((LPWORD)lpPtr)++ = hWinData; sItems++; lstrcpy (lpPtr, ""); lpPtr += lstrlen (lpPtr) + 1; lpBarPtr = (LPBARITEMDATA) lpPtr; lpBarPtr->sType = MTYPE_BARITEM; lpBarPtr->sDisplayMode = DISP_MAINSEP; lpBarPtr->szIconFName[0] = '\0'; lpBarPtr->wIconIndex = 0; lpPtr += sizeof (BARITEMDATA); *((LPWORD)lpPtr)++ = MTYPE_SEP; sItems++; lstrcpy (lpPtr, ""); lpPtr += lstrlen (lpPtr) + 1; lpBarPtr = (LPBARITEMDATA) lpPtr; lpBarPtr->sType = MTYPE_BARITEM; lpBarPtr->sDisplayMode = DISP_DATE; lpBarPtr->szIconFName[0] = '\0'; lpBarPtr->wIconIndex = -1; lpPtr += sizeof (BARITEMDATA); *((LPWORD)lpPtr)++ = MTYPE_FIELD; sItems++; lstrcpy (lpPtr, ""); lpPtr += lstrlen (lpPtr) + 1; lpBarPtr = (LPBARITEMDATA) lpPtr; lpBarPtr->sType = MTYPE_BARITEM; lpBarPtr->sDisplayMode = DISP_TIME; lpBarPtr->szIconFName[0] = '\0'; lpBarPtr->wIconIndex = -1; lpPtr += sizeof (BARITEMDATA); *((LPWORD)lpPtr)++ = MTYPE_FIELD; sItems++; *(LPWORD)lpStart = sItems; // Adjust size of blk GlobalUnlock (hGlobal); hTemp = GlobalReAlloc (hGlobal, lpPtr - lpStart, 0); if (hTemp) hGlobal = hTemp; return hGlobal; } //----------------------------------------------------------- // MakeStatBar - Create a status bar //----------------------------------------------------------- INT MakeStatBar (HWND hWnd, LPSTR lpPtr, HFONT hFont) { INT i; char ch; LPSTR lpStr, lpTemp; HICON hIcon; SBCREATESTRUCT sb; LPBARITEMDATA lpBarPtr; // Clear accel tables AttachAccel (0, 0, 0); //Set field data sb.hFont = hFont; sb.sFields = *((LPWORD)lpPtr)++; for (i = 0; i < sb.sFields; i++) { lpStr = lpPtr; lpPtr += lstrlen (lpPtr) + 1; lpBarPtr = (LPBARITEMDATA) lpPtr; sb.sbi[i].sWidth = -1; sb.sbi[i].fFlags = 0; lpPtr += sizeof (BARITEMDATA); switch (lpBarPtr->sDisplayMode) { case DISP_ICON: hIcon = ExtractIcon (hInst, lpBarPtr->szIconFName, lpBarPtr->wIconIndex); if (hIcon < 3) hIcon = LoadIcon (hInst, "WBIcon1"); // See if accel key in text string ch = 0; lpTemp = lpStr; while (*lpTemp) { if (*lpTemp == '&') { ch = (char)(DWORD)AnsiUpper ((LPSTR)(LONG) *(lpTemp+1)); break; } lpTemp++; } if (hIcon > 2) { sb.sbi[i].pText = (LPSTR)MAKELONG (hIcon, (INT)ch); sb.sbi[i].fFlags |= FLAG_ICON; } else sb.sbi[i].pText = "No Icon"; break; case DISP_TEXT: sb.sbi[i].pText = lpStr; break; case DISP_DATE: // Use longest string to set width sb.sbi[i].pText = "Wednesday March 55, 1995"; break; case DISP_TIME: // Use longest string to set width sb.sbi[i].pText = "12:55 AM"; break; case DISP_MAINSEP: sb.sbi[i].sWidth = 0; sb.sbi[i].pText = 0; sb.sbi[i].fFlags |= FLAG_DIN; break; case DISP_NULL: sb.sbi[i].sWidth = 10; sb.sbi[i].pText = 0; break; } switch (*(LPWORD)lpPtr) { case MTYPE_WINLIST: sb.sbi[i].fFlags |= FLAG_DOUT | STATT_DYNAMENU; sb.sbi[i].dwData = MAKELONG (((LPSUBMENUDATA)lpPtr)->hGlobal, MENU_WINDOWS); lpPtr += sizeof (SUBMENUDATA); break; case MTYPE_SUBMENU: if (fFlags & FLAG_FASTMENU) { sb.sbi[i].fFlags |= FLAG_DOUT | STATT_MENU; GlobalLock (((LPSUBMENUDATA)lpPtr)->hGlobal); sb.sbi[i].dwData = MAKELONG ( ((LPSUBMENUDATA)lpPtr)->hGlobal, UDefMenuOps (((LPSUBMENUDATA)lpPtr)->hGlobal, TRUE)); } else { sb.sbi[i].fFlags |= FLAG_DOUT | STATT_DYNAMENU; sb.sbi[i].dwData = MAKELONG (((LPSUBMENUDATA)lpPtr)->hGlobal, MENU_USERDEF); } lpPtr += sizeof (SUBMENUDATA); break; case MTYPE_PROG: sb.sbi[i].fFlags |= FLAG_DOUT | STATT_BUTTON; sb.sbi[i].dwData = (DWORD)lpStr; lpPtr += sizeof (GITEMDATA); break; case MTYPE_CPL: sb.sbi[i].fFlags |= FLAG_DOUT | STATT_BUTTON; sb.sbi[i].dwData = (DWORD)lpStr; lpPtr += sizeof (CPLITEMDATA); break; case MTYPE_INTERNAL: sb.sbi[i].fFlags |= FLAG_DOUT | STATT_BUTTON; sb.sbi[i].dwData = (DWORD)lpStr; lpPtr += sizeof (INTITEMDATA); break; case MTYPE_FIELD: sb.sbi[i].fFlags |= FLAG_DIN; sb.sbi[i].dwData = 0; lpPtr += sizeof (SEPDATA); break; case MTYPE_SEP: sb.sbi[i].dwData = 0; lpPtr += sizeof (SEPDATA); break; default: sb.sbi[i].sWidth = 10; sb.sbi[i].dwData = 0; lpPtr += sizeof (SEPDATA); MessageBeep(0); wsprintf (szDebug, "**** MakeStatBar --Unknown item type %x****\n", *(LPWORD)lpPtr); OutputDebugString (szDebug); break; } } return StatusBarCreateEx (hMain, &sb); } //============================================================ // General Helper Routines //============================================================ //------------------------------------------------------------ // PrintError - Displays a message box with an error code //------------------------------------------------------------ void PrintError (HWND hWnd, INT rc) { char szErrStr[80]; char szTemp[12]; rc = abs (rc); if (LoadString (hInst, rc, szErrStr, sizeof (szErrStr)) == 0) { wsprintf (szTemp, "%d", rc); lstrcpy (szErrStr, "Error number: "); lstrcat (szErrStr, szTemp); } MessageBox (hWnd, szErrStr, szTitleText, MB_OK | MB_ICONHAND); return; } //------------------------------------------------------------ // MyDisplayDialog - Display a dialog box //------------------------------------------------------------ INT MyDisplayDialog (HINSTANCE hInstance, LPCSTR szDlgName, HWND hWnd, DLGPROC lpDialogProc, LPARAM lParam) { DLGPROC lpDlgProcInst; INT rc; lpDlgProcInst = MakeProcInstance((FARPROC)lpDialogProc, hInstance); rc = DialogBoxParam (hInstance, szDlgName, hWnd, lpDlgProcInst, lParam); FreeProcInstance((FARPROC)lpDlgProcInst); return rc; } //------------------------------------------------------------ // MyWritePrivateProfileInt - Writes an integer to the profile //------------------------------------------------------------ BOOL MyWritePrivateProfileInt (char *szSec, char *szEntry, int Num, char *szProfile) { char szStr[33]; wsprintf (szStr, "%d", Num); return WritePrivateProfileString (szSec, szEntry, szStr, szProfile); } //------------------------------------------------------------ // MyGetFilename - Uses the common File Open dialog box to // query the user for a filename //------------------------------------------------------------ BOOL MyGetFilename (HWND hWnd, char *szFilename, INT sMaxLen, char *szFilter, INT sFilterIndex) { OPENFILENAME ofn; memset (&ofn, 0, sizeof (OPENFILENAME)); *szFilename = '\0'; ofn.lStructSize = sizeof (OPENFILENAME); ofn.hwndOwner = hWnd; ofn.lpstrFilter = szFilter; ofn.nFilterIndex = sFilterIndex; ofn.lpstrFile = szFilename; ofn.nMaxFile = sMaxLen; ofn.lpstrTitle = "Browse"; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; return GetOpenFileName (&ofn); } //------------------------------------------------------------ // MySubClassWindow - Subclasses a window //------------------------------------------------------------ WNDPROC MySubClassWindow (HWND hWnd, WNDPROC lpfnNewProc) { WNDPROC lpfnOldProc; lpfnOldProc = (WNDPROC) GetWindowLong (hWnd, GWL_WNDPROC); SetWindowLong (hWnd, GWL_WNDPROC, (LONG) lpfnNewProc); return lpfnOldProc; } //------------------------------------------------------------ // MyGetFont - Uses the common Choose Font dialog box to // query the user for a font. //------------------------------------------------------------ BOOL MyGetFont (HWND hWnd, LPLOGFONT lpFont, INT *sSize, COLORREF *rgbColor, DWORD dwFlags) { CHOOSEFONT cf; BOOL rc; memset (&cf, 0, sizeof (CHOOSEFONT)); cf.lStructSize = sizeof (CHOOSEFONT); cf.hwndOwner = hWnd; cf.hDC = 0; cf.lpLogFont = lpFont; cf.iPointSize = *sSize; cf.Flags = dwFlags | CF_SCREENFONTS | CF_LIMITSIZE; cf.rgbColors = *rgbColor; cf.lCustData = 0; cf.lpfnHook = 0; cf.lpTemplateName = 0; cf.hInstance = hInst; cf.lpszStyle = 0; cf.nFontType = SCREEN_FONTTYPE; cf.nSizeMin = 0; cf.nSizeMax = 24; rc = ChooseFont (&cf); if (rc) { *rgbColor = cf.rgbColors; *sSize = cf.iPointSize; } return rc; } //------------------------------------------------------------ // MyYield - Yields control to other programs, but returns // if Windows is idle. //------------------------------------------------------------ BOOL MyYield (void) { MSG msg; BOOL bCont; bCont = TRUE; while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) bCont = FALSE; TranslateMessage(&msg); DispatchMessage(&msg); } return bCont; }