home *** CD-ROM | disk | FTP | other *** search
- // *********************************************************
- // AppBar -- Advanced Menu bar for Windows 95/NT
- // All code Copyright (C) 1995, 1996 by Mike Perham
- // mperham@cs.cornell.edu
- //
- // This code MAY NOT be used for any other program without
- // my permission and is forbidden in any shareware/commercial
- // program. This code is provided for educational use only
- // and there are no guarantees or promises implied. Blah blah
- // *********************************************************
-
- ///////////////////////////////////////////////////////////////////////
- // AppBar - the Application behind the window
- // This file encapsulates all I/O, Registry functions,
- // initialization, etc.
- /////////////
- //
- // Known Bugs:
- //
- // Screen saver will not activate in Win95 unless
- // AppBar is autohidden. This must be a problem with
- // Win95, since it works in all cases under NT4.
- //
- // Buttons in Edit Dialog are always gray. If
- // you change the default color of your dialogs,
- // they will stick out like a sore thumb. This is
- // because bitmaps do not have a transparent color
- // unlike icons (which is what the C version uses).
- //
-
- #include "appbar.h"
- #include "globals.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #define new DEBUG_NEW
- #endif
-
- ///////////////////////////////////////////////////
- // Here it is...
-
- AppBar ab;
-
- ///////////////////////////////////////////////////
- // global variables visible in all classes
-
- menu_struct *glob_menu; // "2D" list of menus and apps
- sys_vars sv;
- user_vars uv; // variables set in OptDlg
- app_list *applist; // linear list of all apps
- APPBARDATA abd;
-
- ///////////////////////////////////////////////////
- // Creates the AppBar window
- /////////
-
- BOOL AppBar::ShowAppBar(void)
- {
- abwin = new AppBarWin;
- int flags = (uv.stayontop ? WS_EX_TOPMOST : 0) | WS_EX_TOOLWINDOW;
- abwin->CreateEx(flags, (LPCTSTR) ABClass, "AppBar",
- WS_POPUP | WS_DLGFRAME, 0,
- (uv.bottom ? sv.height - AB_HEIGHT : 0),
- AB_WIDTH, AB_HEIGHT, 0, 0, 0);
- if (!abwin->m_hWnd)
- return FALSE;
-
- CWinThread::m_pMainWnd = abwin;
-
- abwin->ShowWindow(SW_SHOW);
- if (sv.newshell)
- if (uv.autohide)
- abwin->HideAppBar(TRUE);
- else
- abwin->ModifyTime();
- else
- abwin->HideAppBar(TRUE);
- return TRUE;
- }
-
- //////////////////////////////////////////////////
- // Set system vars and parse cmd args and get reg keys
- // This is the first function executed when AppBar is started
- ////////
-
- BOOL AppBar::InitApplication(void)
- {
- HWND OldWnd = FindWindow(NULL, "AppBar");
- if (OldWnd) {
- BringWindowToTop(OldWnd);
- return FALSE;
- }
-
- #ifdef _DEBUG
- begin.Checkpoint(); // Begin debug memory trace
- #endif
-
- /* //This does not compile for some unknown reason
- OSVERSIONINFO ovi;
- ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO)
- GetVersionEx((LPOSVERSIONINFO)&ovi);
- switch (ovi.dwPlatformId) {
- case VER_PLATFORM_WIN32_WINDOWS:
- sv.newshell = TRUE;
- sv.power = FALSE;
- break;
- case VER_PLATFORM_WIN32_NT:
- if (ovi.dwMajorVersion == 4) {
- sv.newshell = TRUE;
- sv.power = FALSE;
- } else if (ovi.dwMajorVersion == 3) {
- sv.newshell = FALSE;
- sv.power = FALSE;
- } else {
- sv.newshell = TRUE;
- sv.power = TRUE;
- }
- break;
- default:
- return FALSE;
- }
- */
-
- DWORD dwVersion = GetVersion();
- DWORD dwMajor = (DWORD)(LOBYTE(LOWORD(dwVersion)));
- DWORD dwMinor = (DWORD)(HIBYTE(LOWORD(dwVersion)));
-
- if (dwVersion < 0x80000000) { // Windows NT
- if (dwMajor == 3) {
- sv.newshell = FALSE;
- sv.power = FALSE;
- } else if (dwMajor == 4) {
- sv.newshell = TRUE;
- sv.power = FALSE;
- } else { // NT5!
- sv.newshell = TRUE;
- sv.power = TRUE;
- }
- } else if (dwMajor < 4) // Win32s
- return FALSE;
- else { // Windows 95 -- No build numbers provided
- sv.newshell = TRUE;
- sv.power = TRUE;
- }
-
- if (sv.power) {
- SYSTEM_POWER_STATUS sps;
- GetSystemPowerStatus(&sps);
- if (sps.ACLineStatus)
- sv.battery = FALSE;
- else
- sv.battery = TRUE;
- }
-
- sv.width = GetSystemMetrics(SM_CXSCREEN);
- sv.height = GetSystemMetrics(SM_CYSCREEN);
-
- // copy AppBar's directory to origdir
- char *end = strrchr(m_pszHelpFilePath, '\\');
- char *front = (char *) m_pszHelpFilePath;
- char *copy = origdir;
-
- while (front != end) {
- *copy = *front;
- copy++; front++;
- }
- *copy = '\0';
-
- SetRegistryKey("Software\\AppBar");
- // parse args AND get registry keys
- ParseCmdArgs();
-
- LPCTSTR temp;
- temp = AfxRegisterWndClass(NULL, NULL, (HBRUSH)COLOR_MENU+1, LoadIcon(IDI_APPBAR));
- ABClass = CString(temp);
- return TRUE;
- }
-
- BOOL AppBar::InitInstance()
- {
- if (!ReadInApps())
- return FALSE;
- return ShowAppBar();
- }
-
- //////////////////////////
- // Reads in the user spec'd applications
-
- BOOL AppBar::ReadInApps(void)
- {
- FILE *appfile;
- int i, j=0, ver;
- BOOL exist = TRUE;
- char msg[80];
- menu_struct *cur_menu, *nextmenu, *prevmenu;
- app_struct *cur_app, *nextapp, *prevapp;
-
- // Create binary data file if none exists
-
- _chdir(origdir);
- if ((appfile = fopen(sv.appfile, "r")) == NULL)
- exist = FALSE;
-
- // Read application data until the end of the file
- // this tests for zero-length data files (exist, but are empty)
- if (exist)
- if (_filelength(_fileno(appfile)) == 0)
- exist = FALSE;
-
- glob_menu = NULL;
- if (exist) {
- fread(&ver, sizeof(int), 1, appfile);
- if (ver != APPBAR_FILE_VERSION) {
- error(OLD_DATAFILE_FORMAT);
- return FALSE;
- }
- cur_menu = new menu_struct;
- glob_menu = cur_menu;
- nextmenu = cur_menu;
- prevmenu = NULL;
- while (fread(nextmenu, sizeof(menu_struct), 1, appfile)) {
- j++;
- cur_menu = nextmenu;
- cur_menu->nextapp = NULL;
- prevapp = NULL;
- cur_menu->prevmenu = prevmenu;
- if (nextmenu->numapps) {
- cur_app = new app_struct;
- cur_menu->nextapp = cur_app;
- for (i=cur_menu->numapps;i>0; i--) {
- if (!fread(cur_app, sizeof(app_struct), 1, appfile)) {
- sprintf(msg, ERROR_READING_MENUS,j,
- cur_menu->numapps - i + 1, sv.appfile);
- error(msg);
- }
- cur_app->prevapp = prevapp;
- prevapp = cur_app;
- if (i-1) {
- cur_app->nextapp = new app_struct;
- cur_app = cur_app->nextapp;
- } else cur_app->nextapp = NULL;
- }
- }
- prevmenu = cur_menu;
- nextmenu = new menu_struct;
- nextmenu->prevmenu = cur_menu;
- cur_menu->nextmenu = nextmenu;
- }
- // Reached EOF. Now we need to delete that last menu, since it was
- // created before we knew it was EOF.
- delete nextmenu;
- cur_menu->nextmenu = NULL;
- fclose(appfile);
- } else {
- // Create default menu structure if no datafile exists
- char path[80];
- menu_struct *tempmenu;
-
- tempmenu = new menu_struct;
- strcpy(tempmenu->menuname,"&Apps");
- tempmenu->numapps = 2;
-
- tempmenu->nextapp = new app_struct;
- strcpy(tempmenu->nextapp->appexe, "c:\\vc40\\bin\\msdev.exe");
- strcpy(tempmenu->nextapp->appname, "Visual &C++ v4.0");
- cur_app = tempmenu->nextapp;
-
- nextapp = new app_struct;
- cur_app->nextapp = nextapp;
- nextapp->prevapp = cur_app;
- strcpy(nextapp->appexe, "c:\\winword\\winword.exe");
- strcpy(nextapp->appname, "&Word v7.0");
- glob_menu = tempmenu;
-
- tempmenu = new menu_struct;
- glob_menu->nextmenu = tempmenu;
- tempmenu->prevmenu = glob_menu;
- strcpy(tempmenu->menuname,"&Games");
- tempmenu->numapps = 2;
-
- tempmenu->nextapp = new app_struct;
- GetWindowsDirectory(path, sizeof(path));
- strcat(path,"\\winmine.exe");
- strcpy(tempmenu->nextapp->appexe, path);
- strcpy(tempmenu->nextapp->appname, "&Minesweeper");
- cur_app = tempmenu->nextapp;
-
- nextapp = new app_struct;
- cur_app->nextapp = nextapp;
- nextapp->prevapp = cur_app;
- GetWindowsDirectory(path, sizeof(path));
- strcat(path,"\\sol.exe");
- strcpy(nextapp->appexe, path);
- strcpy(nextapp->appname, "&Solitaire");
- }
- return TRUE;
- }
-
- //////////////////////////////////////////////////
- // Exit function for appbar
-
- void AppBar::ExitAppBar(BOOL error_exit)
- {
- if (!error_exit) { // if error, just bomb out...
- SaveMenu();
- SaveRegKey();
- release_app_memory();
- }
- CleanUp();
- PostQuitMessage(0);
- }
-
- //////////////////////////////////////////////////
- // Delete and unregister all variables and structs
-
- void AppBar::CleanUp(void)
- {
- if (abwin) {
- if (sv.newshell) {
- abd.cbSize = sizeof(APPBARDATA);
- abd.hWnd = abwin->GetSafeHwnd();
- abd.uEdge = (uv.bottom ? ABE_BOTTOM : ABE_TOP);
- abd.lParam = FALSE;
- SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd);
- SHAppBarMessage(ABM_REMOVE, &abd);
- }
- abwin->DestroyWindow();
- delete abwin;
- }
- UnregisterClass((LPCTSTR)ABClass, m_hInstance);
-
- #ifdef _DEBUG
- end.Checkpoint(); // end memory trace and print stats
- diff.Difference(begin, end);
- diff.DumpStatistics();
- #endif
- }
-
- //////////////////////////////////////////////////
- // Execute application pointed to by app
-
- BOOL AppBar::ExecuteApplication(app_struct * app)
- {
- char msg[200];
- DWORD error;
-
- if (sv.newshell) {
- SHELLEXECUTEINFO sei;
-
- sei.cbSize = sizeof(SHELLEXECUTEINFO);
- sei.fMask = SEE_MASK_DOENVSUBST | SEE_MASK_NOCLOSEPROCESS;
- sei.hwnd = abwin->m_hWnd;
- sei.lpVerb = "open";
- sei.lpFile = app->appexe;
- sei.lpParameters = app->params;
- sei.lpDirectory = app->workingdir;
- sei.nShow = app->show;
-
- ShellExecuteEx(&sei);
- /* error = GetLastError();
- switch (error) {
- case ERROR_FILE_NOT_FOUND:
- sprintf(msg, FILE_NOT_FOUND, app->appexe);
- break;
- case ERROR_PATH_NOT_FOUND:
- sprintf(msg, PATH_NOT_FOUND, app->appexe);
- break;
- case ERROR_NOT_ENOUGH_MEMORY:
- sprintf(msg, OUT_OF_MEM);
- break;
- case ERROR_DLL_NOT_FOUND:
- sprintf(msg, DLL_NOT_FOUND);
- break;
- default:
- sprintf(msg, RETURNED_ERROR, error);
- break;
- }
- ab_message(msg, abwin->GetSafeHwnd());
- return 0;
- }*/
- } else {
- error = (DWORD) ShellExecute(abwin->m_hWnd, "open", app->appexe,
- app->params, app->workingdir, app->show);
- if (error < 32) {
- switch (error) {
- case ERROR_FILE_NOT_FOUND:
- sprintf(msg, FILE_NOT_FOUND, app->appexe);
- break;
- case ERROR_PATH_NOT_FOUND:
- sprintf(msg, PATH_NOT_FOUND, app->appexe);
- break;
- default:
- sprintf(msg, RETURNED_ERROR, error);
- break;
- }
- ab_message(msg, abwin->GetSafeHwnd());
- return 0;
- }
- }
- return 1;
- }
-
- //////////////////////////////////////////////////
- // it's hideous, but it does the job...
-
- void AppBar::ParseCmdArgs(void)
- {
- char msg[80];
- int j;
- user_vars args;
- BOOL done = FALSE;
-
- strcpy(sv.user, "");
- strcpy(sv.appfile, "");
- memset((void*)&args, 0, sizeof(user_vars));
- // now process the array of parameters
- for (j=1;j<__argc;j++) {
- if (!strncmp(__argv[j], "-", 1)) {
- if (!strncmp((char*)__argv[j]+1, "s", 1))
- args.stayontop = -1;
- else if (!strncmp((char*)__argv[j]+1, "c", 1))
- args.chime = -1;
- else if (!strncmp((char*)__argv[j]+1, "b", 1))
- args.bottom = -1;
- else if (!strncmp((char*)__argv[j]+1, "a", 1))
- args.autohide = -1;
- else if (!strncmp((char*)__argv[j]+1, "d", 1))
- args.date = -1;
- else if (!strncmp((char*)__argv[j]+1, "m", 1))
- args.memory = -1;
- else if (!strncmp((char*)__argv[j]+1, "t", 1))
- args.time = -1;
- else if (!strncmp((char*)__argv[j]+1, "u", 1))
- args.user = -1;
- else if (!strncmp((char*)__argv[j]+1, "f", 1)) {
- if ((j+1 <= __argc)) {
- char w = *(__argv[j+1]);
- // if filename does not start with '-' or '+'
- // assume it is a valid filename
- if (!((w == '+') || (w == '-')))
- strcpy((char *)sv.appfile, __argv[++j]);
- else {
- j++;
- ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
- }
- } else
- ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
- } else {
- sprintf(msg, UNKNOWN_OPTION, __argv[j]);
- ab_message(msg, abwin->GetSafeHwnd());
- }
- } else if (!strncmp(__argv[j], "+", 1)) {
- if (!strncmp((char*)__argv[j]+1, "s", 1))
- args.stayontop = 1;
- else if (!strncmp((char*)__argv[j]+1, "c", 1))
- args.chime = 1;
- else if (!strncmp((char*)__argv[j]+1, "a", 1))
- args.autohide = 1;
- else if (!strncmp((char*)__argv[j]+1, "b", 1))
- args.bottom = 1;
- else if (!strncmp((char*)__argv[j]+1, "d", 1))
- args.date = 1;
- else if (!strncmp((char*)__argv[j]+1, "m", 1))
- args.memory = 1;
- else if (!strncmp((char*)__argv[j]+1, "t", 1))
- args.time = 1;
- else if (!strncmp((char*)__argv[j]+1, "u", 1))
- args.user = 1;
- else if (!strncmp((char*)__argv[j]+1, "f", 1)) {
- if ((j+1 <= __argc)) {
- char w = *(__argv[j+1]);
- if (!((w == '+') || (w == '-')))
- strcpy((char *)sv.appfile, __argv[++j]);
- else {
- j++;
- ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
- }
- } else
- ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
- } else {
- sprintf(msg, UNKNOWN_OPTION, __argv[j]);
- ab_message(msg, abwin->GetSafeHwnd());
- }
- } else // User gave a user configuration
- strcpy((char*)sv.user, __argv[j]);
- } // end while
-
- if (strcmp((char*)sv.user, ""))
- sprintf(sv.appfile, "appbar.%s", sv.user);
-
- GetRegKeys(&args);
- }
-
- //////////////////////////////////////////////////
-
- #define SET(a); if (args->a == 1) \
- uv.a = TRUE; \
- else if (args->a == -1) \
- uv.a = FALSE;
-
- void AppBar::GetRegKeys(user_vars *args)
- {
- HKEY root;
- DWORD isnew, type, size = sizeof(user_vars);
- LONG rc;
- char *p, keyname[80], mike[80];
-
- // each user gets his own key in the registry
- if (strlen(sv.user)) {
- strcpy(mike, sv.user);
- // this loop will not work with Unicode
- for (p=mike; p<mike+strlen(mike); p++)
- _tolower(*p);
- sprintf(keyname, "%s\\%s", m_pszRegistryKey, mike);
- } else
- sprintf(keyname, "%s\\Default", m_pszRegistryKey);
-
-
- if (!strcmp(sv.appfile, ""))
- strcpy(sv.appfile, "appbar.default");
- // create or open key
- rc = RegCreateKeyEx(HKEY_CURRENT_USER, keyname, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
- NULL, &root, &isnew);
-
- if (rc != ERROR_SUCCESS) {
- ab_message(ERROR_OPENING_REG, abwin->GetSafeHwnd());
- uv.stayontop = TRUE;
- uv.time = TRUE;
- uv.memory = TRUE;
- uv.autohide = TRUE;
- uv.chime = FALSE;
- uv.date = FALSE;
- uv.bottom = FALSE;
- uv.user = FALSE;
- strcpy(uv.wavfile, "");
- if (strlen(sv.user))
- sprintf(sv.appfile, "appbar.%s", sv.user);
- else
- strcpy(sv.appfile, "appbar.default");
- return;
- }
-
- if (isnew != REG_OPENED_EXISTING_KEY)
- MakeNewRegKey(root);
- else {
- rc = RegQueryValueEx(root, "User_Variables", NULL, &type, (PBYTE)&uv, &size);
- if (size != sizeof(user_vars)) {
- ab_message(OBSOLETE_REG_DATA, abwin->GetSafeHwnd());
- RegDeleteKey(root, "User_Variables");
- MakeNewRegKey(root);
- }
- }
- RegCloseKey(root);
- // modify user vars according to cmd args
- SET(date);
- SET(memory);
- SET(stayontop);
- SET(bottom);
- SET(autohide);
- SET(chime);
- SET(time);
- SET(user);
-
- if (!sv.newshell)
- uv.autohide = TRUE; // autohide is ALWAYS on in WinNT 3
- }
-
- //////////////////////////////////////////////////
-
- void AppBar::MakeNewRegKey(HKEY root)
- {
- char msg[100];
- char comma[3] = "";
- LONG rc;
-
- if (strcmp(sv.user, ""))
- strcpy(comma, ", ");
- sprintf(msg, WELCOME_MSG, comma, sv.user);
- ab_message(msg, abwin->GetSafeHwnd());
- uv.time = TRUE;
- uv.stayontop = TRUE;
- uv.chime = FALSE;
- uv.date = FALSE;
- uv.user = FALSE;
- uv.bottom = FALSE;
- uv.memory = TRUE;
- uv.autohide = TRUE;
- strcpy(uv.wavfile, "");
- rc = RegSetValueEx(root, "User_Variables", NULL, REG_BINARY,
- (PBYTE) &uv, sizeof(user_vars));
- if (rc != ERROR_SUCCESS)
- ab_message(ERROR_SAVING_REG, abwin->GetSafeHwnd());
- }
-
- //////////////////////////////////////////////////
-
- void AppBar::SaveRegKey(void)
- {
- HKEY root;
- char keyname[80];
- DWORD isnew;
-
- if (strcmp((char*)sv.user, ""))
- sprintf(keyname, "%s\\%s", m_pszRegistryKey, sv.user);
- else
- sprintf(keyname, "%s\\Default", m_pszRegistryKey);
-
- if (RegCreateKeyEx(HKEY_CURRENT_USER, keyname, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &root, &isnew))
- ab_message(ERROR_SAVING_REG, abwin->GetSafeHwnd());
- if (RegSetValueEx(root, "User_Variables", NULL, REG_BINARY,
- (PBYTE)&uv, sizeof(user_vars)))
- ab_message(ERROR_SAVING_REG, abwin->GetSafeHwnd());
- RegCloseKey(root);
- }
-
- void AppBar::SaveMenu(void)
- {
- app_struct * pCurApp;
- menu_struct * pCurMenu;
- app_struct *next, *prev, *nexta;
- menu_struct *nextm, *prevm;
- char msg[80];
- FILE *pDataFile;
- int i;
-
- _chdir(origdir);
- pDataFile = fopen(sv.appfile, "wb"); // Open for binary write
-
- if (!pDataFile) {
- sprintf(msg, ERROR_OPENING_DATAFILE, sv.appfile);
- ab_message(msg, abwin->GetSafeHwnd());
- return;
- }
-
- i = APPBAR_FILE_VERSION;
- fwrite(&i, sizeof(int), 1, pDataFile);
- for (pCurMenu = glob_menu; pCurMenu != NULL; pCurMenu = pCurMenu->nextmenu) {
- nextm = pCurMenu->nextmenu;
- prevm = pCurMenu->prevmenu;
- nexta = pCurMenu->nextapp;
- pCurMenu->nextapp = NULL;
- pCurMenu->nextmenu = NULL;
- pCurMenu->prevmenu = NULL;
- fwrite(pCurMenu, sizeof(menu_struct), 1, pDataFile);
- pCurMenu->nextapp = nexta;
- pCurMenu->nextmenu = nextm;
- pCurMenu->prevmenu = prevm;
- for (pCurApp = pCurMenu->nextapp; pCurApp != NULL; pCurApp = pCurApp->nextapp) {
- next = pCurApp->nextapp;
- prev = pCurApp->prevapp;
- pCurApp->nextapp = NULL;
- pCurApp->prevapp = NULL;
- fwrite(pCurApp, sizeof(app_struct), 1, pDataFile);
- pCurApp->nextapp = next;
- pCurApp->prevapp = prev;
- }
- }
- fclose(pDataFile);
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // C++ Constructors and Destructors //
- ///////////////////////////////////////////////////////////////////////////
-
- menu_struct::menu_struct()
- {
- memset((void*)menuname, 0, sizeof(menuname));
- numapps = 0;
- nextmenu = NULL;
- prevmenu = NULL;
- nextapp = NULL;
- }
-
- menu_struct::~menu_struct()
- {
- if (nextmenu == NULL) {
- if (prevmenu != NULL)
- prevmenu->nextmenu = NULL;
- else
- glob_menu = NULL;
- }
- else if (prevmenu == NULL) {
- glob_menu = nextmenu;
- nextmenu->prevmenu = NULL;
- }
- else {
- if (prevmenu)
- prevmenu->nextmenu = nextmenu;
- if (nextmenu)
- nextmenu->prevmenu = prevmenu;
- }
- }
-
- app_struct::app_struct()
- {
- memset((void*)appexe, 0, sizeof(appexe));
- memset((void*)workingdir, 0, sizeof(workingdir));
- memset((void*)params, 0, sizeof(params));
- memset((void*)appname, 0, sizeof(appname));
- show = 0;
- separator = FALSE;
- nextapp = NULL;
- prevapp = NULL;
- }
-
- app_struct::~app_struct()
- {
- if (nextapp == NULL) {
- if (prevapp != NULL)
- prevapp->nextapp = NULL;
- }
- else if (prevapp == NULL)
- nextapp->prevapp = NULL;
- else {
- prevapp->nextapp = nextapp;
- nextapp->prevapp = prevapp;
- }
- }
-