mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-24 11:09:01 +08:00
win32 systray functionality
This commit is contained in:
parent
2b732a8067
commit
1a9b36e842
132
main.c
132
main.c
@ -58,6 +58,7 @@
|
||||
static int exit_flag;
|
||||
static char *options[MAX_OPTIONS];
|
||||
static char server_name[40];
|
||||
static char *config_file;
|
||||
static struct mg_context *ctx;
|
||||
|
||||
#if !defined(CONFIG_FILE)
|
||||
@ -178,27 +179,26 @@ static void set_option(char **options, const char *name, const char *value) {
|
||||
}
|
||||
|
||||
static void process_command_line_arguments(char *argv[], char **options) {
|
||||
const char *config_file = NULL;
|
||||
char line[512], opt[512], val[512], path[PATH_MAX], *p;
|
||||
FILE *fp = NULL;
|
||||
struct stat st;
|
||||
size_t i, line_no = 0;
|
||||
|
||||
/* Should we use a config file ? */
|
||||
if (argv[1] != NULL && argv[2] == NULL) {
|
||||
config_file = argv[1];
|
||||
} else if (argv[1] == NULL && (p = strrchr(argv[0], DIRSEP)) == NULL) {
|
||||
} else if ((p = strrchr(argv[0], DIRSEP)) == NULL) {
|
||||
// No command line flags specified. Look where binary lives
|
||||
config_file = CONFIG_FILE;
|
||||
} else if (argv[1] == NULL) {
|
||||
} else {
|
||||
snprintf(path, sizeof(path), "%.*s%c%s",
|
||||
(int) (p - argv[0]), argv[0], DIRSEP, CONFIG_FILE);
|
||||
if (stat(path, &st) == 0) {
|
||||
config_file = path;
|
||||
}
|
||||
}
|
||||
|
||||
fp = fopen(config_file, "r");
|
||||
|
||||
/* If config file was set in command line and open failed, exit */
|
||||
if (config_file != NULL && (fp = fopen(config_file, "r")) == NULL) {
|
||||
if (argv[1] != NULL && argv[2] == NULL && fp == NULL) {
|
||||
die("Cannot open config file %s: %s", config_file, strerror(errno));
|
||||
}
|
||||
|
||||
@ -231,12 +231,14 @@ static void process_command_line_arguments(char *argv[], char **options) {
|
||||
}
|
||||
}
|
||||
|
||||
static void init_server_name(void) {
|
||||
snprintf(server_name, sizeof(server_name), "Mongoose web server v.%s",
|
||||
mg_version());
|
||||
}
|
||||
|
||||
static void start_mongoose(int argc, char *argv[]) {
|
||||
int i;
|
||||
|
||||
snprintf(server_name, sizeof(server_name),
|
||||
"Mongoose %s web server", mg_version());
|
||||
|
||||
/* Edit passwords file if -A option is specified */
|
||||
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'A') {
|
||||
if (argc != 6) {
|
||||
@ -294,7 +296,6 @@ static void WINAPI ServiceMain(void) {
|
||||
hStatus = RegisterServiceCtrlHandler(server_name, ControlHandler);
|
||||
SetServiceStatus(hStatus, &ss);
|
||||
|
||||
//Sleep(3000);
|
||||
while (ss.dwCurrentState == SERVICE_RUNNING) {
|
||||
Sleep(1000);
|
||||
}
|
||||
@ -305,43 +306,89 @@ static void WINAPI ServiceMain(void) {
|
||||
SetServiceStatus(hStatus, &ss);
|
||||
}
|
||||
|
||||
static void try_to_run_as_nt_service(void) {
|
||||
#define ID_TRAYICON 100
|
||||
#define ID_QUIT 101
|
||||
#define ID_EDIT_CONFIG 102
|
||||
#define ID_SEPARATOR 103
|
||||
#define ID_INSTALL_SERVICE 104
|
||||
#define ID_REMOVE_SERVICE 105
|
||||
#define ID_ICON 200
|
||||
static NOTIFYICONDATA TrayIcon;
|
||||
|
||||
static void edit_config_file(void) {
|
||||
const char **names, *value;
|
||||
FILE *fp;
|
||||
int i;
|
||||
char cmd[200];
|
||||
|
||||
// Create config file if it is not present yet
|
||||
if ((fp = fopen(config_file, "r")) != NULL) {
|
||||
fclose(fp);
|
||||
} else if ((fp = fopen(config_file, "a+")) != NULL) {
|
||||
fprintf(fp,
|
||||
"# Mongoose web server configuration file.\n"
|
||||
"# Lines starting with '#' and empty lines are ignored.\n"
|
||||
"# For detailed description of every option, visit\n"
|
||||
"# http://code.google.com/p/mongoose/wiki/MongooseManual\n\n");
|
||||
names = mg_get_valid_option_names();
|
||||
for (i = 0; names[i] != NULL; i += 3) {
|
||||
value = mg_get_option(ctx, names[i]);
|
||||
fprintf(fp, "# %s %s\n", names[i + 1], *value ? value : "<value>");
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "notepad.exe %s", config_file);
|
||||
WinExec(cmd, SW_SHOW);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
static SERVICE_TABLE_ENTRY service_table[] = {
|
||||
{server_name, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
if (StartServiceCtrlDispatcher(service_table)) {
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
#define ID_TRAYICON 100
|
||||
#define ID_QUIT 101
|
||||
static NOTIFYICONDATA ni;
|
||||
|
||||
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
POINT pt;
|
||||
HMENU hMenu;
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_CREATE:
|
||||
// Win32 runtime must prepare __argc and __argv for us
|
||||
start_mongoose(__argc, __argv);
|
||||
// TODO(lsm): figure out why this executes long time
|
||||
if (StartServiceCtrlDispatcher(service_table)) {
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case ID_QUIT:
|
||||
exit(EXIT_SUCCESS);
|
||||
mg_stop(ctx);
|
||||
Shell_NotifyIcon(NIM_DELETE, &TrayIcon);
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case ID_EDIT_CONFIG:
|
||||
edit_config_file();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_USER:
|
||||
switch (lParam) {
|
||||
case WM_RBUTTONUP:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
hMenu = CreatePopupMenu();
|
||||
AppendMenu(hMenu, 0, ID_QUIT, "Exit");
|
||||
AppendMenu(hMenu, MF_STRING | MF_GRAYED, ID_SEPARATOR, server_name);
|
||||
AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, "");
|
||||
#if 0
|
||||
AppendMenu(hMenu, MF_STRING | MF_GRAYED, ID_SEPARATOR,
|
||||
"NT service: not installed");
|
||||
AppendMenu(hMenu, MF_STRING, ID_INSTALL_SERVICE, "Install");
|
||||
AppendMenu(hMenu, MF_STRING, ID_REMOVE_SERVICE, "Deinstall");
|
||||
AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, "");
|
||||
#endif
|
||||
AppendMenu(hMenu, MF_STRING, ID_EDIT_CONFIG, "Edit config file");
|
||||
AppendMenu(hMenu, MF_STRING, ID_QUIT, "Exit");
|
||||
GetCursorPos(&pt);
|
||||
TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hWnd, NULL);
|
||||
DestroyMenu(hMenu);
|
||||
@ -358,10 +405,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdline, int show) {
|
||||
HWND hWnd;
|
||||
MSG msg;
|
||||
|
||||
// Win32 runtime must prepare __argc and __argv for us
|
||||
start_mongoose(__argc, __argv);
|
||||
try_to_run_as_nt_service();
|
||||
|
||||
init_server_name();
|
||||
memset(&cls, 0, sizeof(cls));
|
||||
cls.lpfnWndProc = (WNDPROC) WindowProc;
|
||||
cls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
@ -372,23 +416,24 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdline, int show) {
|
||||
0, 0, 0, 0, NULL, NULL, NULL, NULL);
|
||||
ShowWindow(hWnd, SW_HIDE);
|
||||
|
||||
ni.cbSize = sizeof(ni);
|
||||
ni.uID = ID_TRAYICON;
|
||||
ni.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
|
||||
ni.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
ni.hWnd = hWnd;
|
||||
snprintf(ni.szTip, sizeof(ni.szTip), "%s", server_name);
|
||||
ni.uCallbackMessage = WM_USER;
|
||||
Shell_NotifyIcon(NIM_ADD, &ni);
|
||||
TrayIcon.cbSize = sizeof(TrayIcon);
|
||||
TrayIcon.uID = ID_TRAYICON;
|
||||
TrayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
|
||||
TrayIcon.hIcon = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_ICON),
|
||||
IMAGE_ICON, 16, 16, 0);
|
||||
TrayIcon.hWnd = hWnd;
|
||||
snprintf(TrayIcon.szTip, sizeof(TrayIcon.szTip), "%s", server_name);
|
||||
TrayIcon.uCallbackMessage = WM_USER;
|
||||
Shell_NotifyIcon(NIM_ADD, &TrayIcon);
|
||||
|
||||
while (GetMessage(&msg, hWnd, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
int WINCDECL main(int argc, char *argv[]) {
|
||||
#else
|
||||
int main(int argc, char *argv[]) {
|
||||
init_server_name();
|
||||
start_mongoose(argc, argv);
|
||||
printf("%s started on port(s) %s with web root [%s]\n",
|
||||
server_name, mg_get_option(ctx, "listening_ports"),
|
||||
@ -404,3 +449,4 @@ int WINCDECL main(int argc, char *argv[]) {
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
1
win32/res.rc
Normal file
1
win32/res.rc
Normal file
@ -0,0 +1 @@
|
||||
200 ICON DISCARDABLE "systray.ico"
|
BIN
win32/systray.ico
Normal file
BIN
win32/systray.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in New Issue
Block a user