static void enableScreensControls(HWND hwnd) { // decide if edit and remove buttons should be enabled bool client = isClientChecked(hwnd); bool screenSelected = false; if (!client) { HWND child = getItem(hwnd, IDC_MAIN_SERVER_SCREENS_LIST); if (SendMessage(child, LB_GETCURSEL, 0, 0) != LB_ERR) { screenSelected = true; } } // enable/disable controls enableItem(hwnd, IDC_MAIN_SERVER_SCREENS_LABEL, !client); enableItem(hwnd, IDC_MAIN_SERVER_SCREENS_LIST, !client); enableItem(hwnd, IDC_MAIN_SERVER_ADD_BUTTON, !client); enableItem(hwnd, IDC_MAIN_SERVER_EDIT_BUTTON, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_REMOVE_BUTTON, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_LAYOUT_LABEL, !client); enableItem(hwnd, IDC_MAIN_SERVER_LEFT_COMBO, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_RIGHT_COMBO, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_TOP_COMBO, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_BOTTOM_COMBO, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_LEFT_LABEL, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_RIGHT_LABEL, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_TOP_LABEL, screenSelected); enableItem(hwnd, IDC_MAIN_SERVER_BOTTOM_LABEL, screenSelected); }
static HANDLE launchApp(HWND hwnd, bool testing, DWORD* threadID) { // decide if client or server const bool isClient = isClientChecked(hwnd); const char* app = isClient ? CLIENT_APP : SERVER_APP; // prepare command line CString cmdLine = getCommandLine(hwnd, testing, false); if (cmdLine.empty()) { return NULL; } // start child PROCESS_INFORMATION procInfo; if (!execApp(app, cmdLine, &procInfo)) { showError(hwnd, CStringUtil::format( getString(IDS_STARTUP_FAILED).c_str(), getErrorString(GetLastError()).c_str())); return NULL; } // don't need process handle CloseHandle(procInfo.hProcess); // save thread ID if desired if (threadID != NULL) { *threadID = procInfo.dwThreadId; } // return thread handle return procInfo.hThread; }
static void enableMainWindowControls(HWND hwnd) { bool client = isClientChecked(hwnd); enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_LABEL, client); enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT, client); enableItem(hwnd, IDC_MAIN_SERVER_SCREENS_LABEL, !client); enableItem(hwnd, IDC_MAIN_SCREENS, !client); }
static void saveMainWindow(HWND hwnd) { HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath()); if (key != NULL) { HWND child; child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT); CArchMiscWindows::setValue(key, "server", getWindowText(child)); child = getItem(hwnd, IDC_MAIN_DEBUG); CArchMiscWindows::setValue(key, "debug", SendMessage(child, CB_GETCURSEL, 0, 0)); CArchMiscWindows::setValue(key, "isServer", isClientChecked(hwnd) ? 0 : 1); CArchMiscWindows::closeKey(key); } }
static LRESULT CALLBACK mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: // save data if (saveMainWindow(hwnd, true)) { // quit PostQuitMessage(0); } return 0; case IDOK: case IDC_MAIN_TEST: { // note if testing const bool testing = (LOWORD(wParam) == IDC_MAIN_TEST); // save data if (saveMainWindow(hwnd, false)) { // launch child app DWORD threadID; HANDLE thread = launchApp(hwnd, testing, &threadID); if (thread == NULL) { return 0; } // handle child program if (testing) { // wait for process to stop, allowing the user to kill it waitForChild(hwnd, thread, threadID); // clean up CloseHandle(thread); } else { // don't need thread handle CloseHandle(thread); // notify of success askOkay(hwnd, getString(IDS_STARTED_TITLE), getString(IDS_STARTED)); // quit PostQuitMessage(0); } } return 0; } case IDC_MAIN_AUTOSTART: { CString cmdLine; if (saveMainWindow(hwnd, false, &cmdLine)) { // run dialog CAutoStart autoStart(hwnd, !isClientChecked(hwnd), cmdLine); autoStart.doModal(); } return 0; } case IDC_MAIN_CLIENT_RADIO: case IDC_MAIN_SERVER_RADIO: enableMainWindowControls(hwnd); return 0; case IDC_MAIN_SCREENS: s_screensLinks->doModal(); break; case IDC_MAIN_OPTIONS: s_globalOptions->doModal(); break; case IDC_MAIN_ADVANCED: s_advancedOptions->doModal(isClientChecked(hwnd)); break; } default: break; } return DefDlgProc(hwnd, message, wParam, lParam); }
static bool saveMainWindow(HWND hwnd, bool quiting, CString* cmdLineOut = NULL) { DWORD errorID = 0; CString arg; CString cmdLine; // save dialog state bool isClient = isClientChecked(hwnd); HKEY key = CArchMiscWindows::addKey(HKEY_CURRENT_USER, getSettingsPath()); if (key != NULL) { HWND child; child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT); CArchMiscWindows::setValue(key, "server", getWindowText(child)); child = getItem(hwnd, IDC_MAIN_DEBUG); CArchMiscWindows::setValue(key, "debug", SendMessage(child, CB_GETCURSEL, 0, 0)); CArchMiscWindows::setValue(key, "isServer", isClient ? 0 : 1); CArchMiscWindows::closeKey(key); } // save user's configuration if (!saveConfig(ARG->m_config, false)) { errorID = IDS_SAVE_FAILED; arg = getErrorString(GetLastError()); goto failed; } // save autostart configuration if (CAutoStart::isDaemonInstalled()) { if (!saveConfig(ARG->m_config, true)) { errorID = IDS_AUTOSTART_SAVE_FAILED; arg = getErrorString(GetLastError()); goto failed; } } // get autostart command cmdLine = getCommandLine(hwnd, false, quiting); if (cmdLineOut != NULL) { *cmdLineOut = cmdLine; } if (cmdLine.empty()) { return quiting; } // save autostart command if (CAutoStart::isDaemonInstalled()) { try { CAutoStart::reinstallDaemon(isClient, cmdLine); CAutoStart::uninstallDaemons(!isClient); } catch (XArchDaemon& e) { errorID = IDS_INSTALL_GENERIC_ERROR; arg = e.what(); goto failed; } } return true; failed: CString errorMessage = CStringUtil::format(getString(errorID).c_str(), arg.c_str()); if (quiting) { errorMessage += "\n"; errorMessage += getString(IDS_UNSAVED_DATA_REALLY_QUIT); if (askVerify(hwnd, errorMessage)) { return true; } } else { showError(hwnd, errorMessage); } return false; }
static CString getCommandLine(HWND hwnd, bool testing, bool silent) { CString cmdLine; // add constant testing args if (testing) { cmdLine += " -z --no-restart --no-daemon"; } // can't start as service on NT else if (!CArchMiscWindows::isWindows95Family()) { cmdLine += " --no-daemon"; } // get the server name CString server; bool isClient = isClientChecked(hwnd); if (isClient) { // check server name HWND child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT); server = getWindowText(child); if (!ARG->m_config.isValidScreenName(server)) { if (!silent) { showError(hwnd, CStringUtil::format( getString(IDS_INVALID_SERVER_NAME).c_str(), server.c_str())); } SetFocus(child); return CString(); } // compare server name to local host. a common error // is to provide the client's name for the server. we // don't bother to check the addresses though that'd be // more accurate. if (CStringUtil::CaselessCmp::equal(ARCH->getHostName(), server)) { if (!silent) { showError(hwnd, CStringUtil::format( getString(IDS_SERVER_IS_CLIENT).c_str(), server.c_str())); } SetFocus(child); return CString(); } } // debug level. always include this. if (true) { HWND child = getItem(hwnd, IDC_MAIN_DEBUG); int debug = (int)SendMessage(child, CB_GETCURSEL, 0, 0); // if testing then we force the debug level to be no less than // s_minTestDebug. what's the point of testing if you can't // see the debugging info? if (testing && debug < s_minTestDebug) { debug = s_minTestDebug; } cmdLine += " --debug "; cmdLine += s_debugName[debug][1]; } // add advanced options cmdLine += s_advancedOptions->getCommandLine(isClient, server); return cmdLine; }
static LRESULT CALLBACK mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: // test for unsaved data if (ARG->m_config != ARG->m_oldConfig) { if (!askVerify(hwnd, getString(IDS_UNSAVED_DATA_REALLY_QUIT))) { return 0; } } // quit PostQuitMessage(0); return 0; case IDOK: case IDC_MAIN_TEST: { // note if testing const bool testing = (LOWORD(wParam) == IDC_MAIN_TEST); // save data if (ARG->m_config != ARG->m_oldConfig) { if (!saveConfig(ARG->m_config, false)) { showError(hwnd, CStringUtil::format( getString(IDS_SAVE_FAILED).c_str(), getErrorString(GetLastError()).c_str())); return 0; } ARG->m_oldConfig = ARG->m_config; enableSaveControls(hwnd); } // launch child app DWORD threadID; HANDLE thread = launchApp(hwnd, testing, &threadID); if (thread == NULL) { return 0; } // handle child program if (testing) { // wait for process to stop, allowing the user to kill it waitForChild(hwnd, thread, threadID); // clean up CloseHandle(thread); } else { // don't need thread handle CloseHandle(thread); // notify of success askOkay(hwnd, getString(IDS_STARTED_TITLE), getString(IDS_STARTED)); // quit PostQuitMessage(0); } return 0; } case IDC_MAIN_AUTOSTART: { // construct command line CString cmdLine = getCommandLine(hwnd, false); if (!cmdLine.empty()) { // run dialog CAutoStart autoStart(hwnd, isClientChecked(hwnd) ? NULL : &ARG->m_config, cmdLine); autoStart.doModal(); if (autoStart.wasUserConfigSaved()) { ARG->m_oldConfig = ARG->m_config; enableSaveControls(hwnd); } } return 0; } case IDC_MAIN_SAVE: if (!saveConfig(ARG->m_config, false)) { showError(hwnd, CStringUtil::format( getString(IDS_SAVE_FAILED).c_str(), getErrorString(GetLastError()).c_str())); } else { ARG->m_oldConfig = ARG->m_config; enableSaveControls(hwnd); } return 0; case IDC_MAIN_CLIENT_RADIO: case IDC_MAIN_SERVER_RADIO: enableMainWindowControls(hwnd); return 0; case IDC_MAIN_SERVER_ADD_BUTTON: addScreen(hwnd); return 0; case IDC_MAIN_SERVER_EDIT_BUTTON: editScreen(hwnd); return 0; case IDC_MAIN_SERVER_REMOVE_BUTTON: removeScreen(hwnd); return 0; case IDC_MAIN_SERVER_SCREENS_LIST: if (HIWORD(wParam) == LBN_SELCHANGE) { enableScreensControls(hwnd); updateNeighbors(hwnd); } else if (HIWORD(wParam) == LBN_DBLCLK) { editScreen(hwnd); return 0; } break; case IDC_MAIN_SERVER_LEFT_COMBO: if (HIWORD(wParam) == CBN_SELENDOK) { changeNeighbor(hwnd, (HWND)lParam, kLeft); return 0; } break; case IDC_MAIN_SERVER_RIGHT_COMBO: if (HIWORD(wParam) == CBN_SELENDOK) { changeNeighbor(hwnd, (HWND)lParam, kRight); return 0; } break; case IDC_MAIN_SERVER_TOP_COMBO: if (HIWORD(wParam) == CBN_SELENDOK) { changeNeighbor(hwnd, (HWND)lParam, kTop); return 0; } break; case IDC_MAIN_SERVER_BOTTOM_COMBO: if (HIWORD(wParam) == CBN_SELENDOK) { changeNeighbor(hwnd, (HWND)lParam, kBottom); return 0; } break; case IDC_MAIN_OPTIONS: s_globalOptions->doModal(); enableSaveControls(hwnd); break; case IDC_MAIN_ADVANCED: s_advancedOptions->doModal(isClientChecked(hwnd)); enableSaveControls(hwnd); break; } default: break; } return DefDlgProc(hwnd, message, wParam, lParam); }
static LRESULT CALLBACK mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_ACTIVATE: if (LOWORD(wParam) != WA_INACTIVE) { // activated // see if the configuration changed if (isConfigNewer(s_configTime, s_userConfig)) { CString message2 = getString(IDS_CONFIG_CHANGED); if (askVerify(hwnd, message2)) { time_t configTime; bool userConfig; CConfig newConfig; if (loadConfig(newConfig, configTime, userConfig) && userConfig == s_userConfig) { ARG->m_config = newConfig; s_lastConfig = ARG->m_config; } else { message2 = getString(IDS_LOAD_FAILED); showError(hwnd, message2); s_lastConfig = CConfig(); } } } } else { // deactivated; write configuration if (!isShowingDialog()) { saveMainWindow(hwnd, SAVE_QUIET); } } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: // save data if (saveMainWindow(hwnd, SAVE_QUITING)) { // quit PostQuitMessage(0); } return 0; case IDOK: case IDC_MAIN_TEST: { // note if testing const bool testing = (LOWORD(wParam) == IDC_MAIN_TEST); // save data if (saveMainWindow(hwnd, SAVE_NORMAL)) { // launch child app DWORD threadID; HANDLE thread; if (!launchApp(hwnd, testing, &thread, &threadID)) { return 0; } // handle child program if (testing) { // wait for process to stop, allowing the user to kill it waitForChild(hwnd, thread, threadID); // clean up CloseHandle(thread); } else { // don't need thread handle if (thread != NULL) { CloseHandle(thread); } // notify of success: now disabled - it's silly to notify a success //askOkay(hwnd, getString(IDS_STARTED_TITLE), getString(IDS_STARTED)); // quit PostQuitMessage(0); } } return 0; } case IDC_MAIN_AUTOSTART: { CString cmdLine; if (saveMainWindow(hwnd, SAVE_NORMAL, &cmdLine)) { // run dialog CAutoStart autoStart(hwnd, !isClientChecked(hwnd), cmdLine); autoStart.doModal(); } return 0; } case IDC_MAIN_CLIENT_RADIO: case IDC_MAIN_SERVER_RADIO: enableMainWindowControls(hwnd); return 0; case IDC_MAIN_SCREENS: s_screensLinks->doModal(); break; case IDC_MAIN_OPTIONS: s_globalOptions->doModal(); break; case IDC_MAIN_ADVANCED: s_advancedOptions->doModal(isClientChecked(hwnd)); break; case IDC_MAIN_HOTKEYS: s_hotkeyOptions->doModal(); break; case IDC_MAIN_INFO: s_info->doModal(); break; } default: break; } return DefDlgProc(hwnd, message, wParam, lParam); }