Localised (almost) all messages.
[nssm.git] / gui.cpp
1 #include "nssm.h"\r
2 \r
3 int nssm_gui(int resource, char *name) {\r
4   /* Create window */\r
5   HWND dlg = CreateDialog(0, MAKEINTRESOURCE(resource), 0, install_dlg);\r
6   if (! dlg) {\r
7     popup_message(MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));\r
8     return 1;\r
9   }\r
10 \r
11   /* Display the window */\r
12   centre_window(dlg);\r
13   ShowWindow(dlg, SW_SHOW);\r
14 \r
15   /* Set service name if given */\r
16   if (name) {\r
17     SetDlgItemText(dlg, IDC_NAME, name);\r
18     /* No point making user click remove if the name is already entered */\r
19     if (resource == IDD_REMOVE) {\r
20       HWND button = GetDlgItem(dlg, IDC_REMOVE);\r
21       if (button) {\r
22         SendMessage(button, WM_LBUTTONDOWN, 0, 0);\r
23         SendMessage(button, WM_LBUTTONUP, 0, 0);\r
24       }\r
25     }\r
26   }\r
27 \r
28   /* Go! */\r
29   MSG message;\r
30   while (GetMessage(&message, 0, 0, 0)) {\r
31     TranslateMessage(&message);\r
32     DispatchMessage(&message);\r
33   }\r
34 \r
35   return (int) message.wParam;\r
36 }\r
37 \r
38 void centre_window(HWND window) {\r
39   HWND desktop;\r
40   RECT size, desktop_size;\r
41   unsigned long x, y;\r
42 \r
43   if (! window) return;\r
44 \r
45   /* Find window size */\r
46   if (! GetWindowRect(window, &size)) return;\r
47   \r
48   /* Find desktop window */\r
49   desktop = GetDesktopWindow();\r
50   if (! desktop) return;\r
51 \r
52   /* Find desktop window size */\r
53   if (! GetWindowRect(desktop, &desktop_size)) return;\r
54 \r
55   /* Centre window */\r
56   x = (desktop_size.right - size.right) / 2;\r
57   y = (desktop_size.bottom - size.bottom) / 2;\r
58   MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);\r
59 }\r
60 \r
61 /* Install the service */\r
62 int install(HWND window) {\r
63   if (! window) return 1;\r
64 \r
65   /* Check parameters in the window */\r
66   char name[STRING_SIZE];\r
67   char exe[EXE_LENGTH];\r
68   char flags[STRING_SIZE];\r
69 \r
70   /* Get service name */\r
71   if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {\r
72     popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);\r
73     return 2;\r
74   }\r
75 \r
76   /* Get executable name */\r
77   if (! GetDlgItemText(window, IDC_PATH, exe, sizeof(exe))) {\r
78     popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);\r
79     return 3;\r
80   }\r
81 \r
82   /* Get flags */\r
83   if (SendMessage(GetDlgItem(window, IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {\r
84     if (! GetDlgItemText(window, IDC_FLAGS, flags, sizeof(flags))) {\r
85       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);\r
86       return 4;\r
87     }\r
88   }\r
89   else ZeroMemory(&flags, sizeof(flags));\r
90 \r
91   /* See if it works */\r
92   switch (install_service(name, exe, flags)) {\r
93     case 2:\r
94       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);\r
95       return 2;\r
96 \r
97     case 3:\r
98       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);\r
99       return 3;\r
100 \r
101     case 4:\r
102       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);\r
103       return 4;\r
104 \r
105     case 5:\r
106       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);\r
107       return 5;\r
108 \r
109     case 6:\r
110       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);\r
111       return 6;\r
112   }\r
113 \r
114   popup_message(MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, name);\r
115   return 0;\r
116 }\r
117 \r
118 /* Remove the service */\r
119 int remove(HWND window) {\r
120   if (! window) return 1;\r
121 \r
122   /* Check parameters in the window */\r
123   char name[STRING_SIZE];\r
124 \r
125   /* Get service name */\r
126   if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {\r
127     popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);\r
128     return 2;\r
129   }\r
130 \r
131   /* Confirm */\r
132   if (popup_message(MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, name) != IDYES) return 0;\r
133 \r
134   /* See if it works */\r
135   switch (remove_service(name)) {\r
136     case 2:\r
137       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);\r
138       return 2;\r
139 \r
140     case 3:\r
141       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);\r
142       return 3;\r
143 \r
144     case 4:\r
145       popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);\r
146       return 4;\r
147   }\r
148 \r
149   popup_message(MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, name);\r
150   return 0;\r
151 }\r
152 \r
153 /* Browse for application */\r
154 void browse(HWND window) {\r
155   if (! window) return;\r
156 \r
157   unsigned long bufsize = 256;\r
158   unsigned long len = bufsize;\r
159   OPENFILENAME ofn;\r
160   ZeroMemory(&ofn, sizeof(ofn));\r
161   ofn.lStructSize = sizeof(ofn);\r
162   ofn.lpstrFilter = (char *) HeapAlloc(GetProcessHeap(), 0, bufsize);\r
163   /* XXX: Escaping nulls with FormatMessage is tricky */\r
164   if (ofn.lpstrFilter) {\r
165     ZeroMemory((void *) ofn.lpstrFilter, bufsize);\r
166     char *localised = message_string(NSSM_GUI_BROWSE_FILTER_APPLICATIONS);\r
167     _snprintf((char *) ofn.lpstrFilter, bufsize, localised);\r
168     /* "Applications" + NULL + "*.exe" + NULL */\r
169     len = strlen(localised) + 1;\r
170     LocalFree(localised);\r
171     _snprintf((char *) ofn.lpstrFilter + len, bufsize - len, "*.exe");\r
172     /* "All files" + NULL + "*.*" + NULL */\r
173     len += 6;\r
174     localised = message_string(NSSM_GUI_BROWSE_FILTER_ALL_FILES);\r
175     _snprintf((char *) ofn.lpstrFilter + len, bufsize - len, localised);\r
176     len += strlen(localised) + 1;\r
177     LocalFree(localised);\r
178     _snprintf((char *) ofn.lpstrFilter + len, bufsize - len, "*.*");\r
179     /* Remainder of the buffer is already zeroed */\r
180   }\r
181   ofn.lpstrFile = new char[MAX_PATH];\r
182   ofn.lpstrFile[0] = '\0';\r
183   ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);\r
184   ofn.nMaxFile = MAX_PATH;\r
185   ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;\r
186 \r
187   if (GetOpenFileName(&ofn)) {\r
188     SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);\r
189   }\r
190   if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);\r
191 \r
192   delete[] ofn.lpstrFile;\r
193 }\r
194 \r
195 /* Install/remove dialogue callback */\r
196 INT_PTR CALLBACK install_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {\r
197   switch (message) {\r
198     /* Creating the dialogue */\r
199     case WM_INITDIALOG:\r
200       return 1;\r
201 \r
202     /* Button was pressed or control was controlled */\r
203     case WM_COMMAND:\r
204       switch (LOWORD(w)) {\r
205         /* OK button */\r
206         case IDC_OK:\r
207           PostQuitMessage(install(window));\r
208           break;\r
209 \r
210         /* Cancel button */\r
211         case IDC_CANCEL:\r
212           DestroyWindow(window);\r
213           break;\r
214 \r
215         /* Browse button */\r
216         case IDC_BROWSE:\r
217           browse(GetDlgItem(window, IDC_PATH));\r
218           break;\r
219 \r
220         /* Remove button */\r
221         case IDC_REMOVE:\r
222           PostQuitMessage(remove(window));\r
223           break;\r
224       }\r
225       return 1;\r
226 \r
227     /* Window closing */\r
228     case WM_CLOSE:\r
229       DestroyWindow(window);\r
230       return 0;\r
231     case WM_DESTROY:\r
232       PostQuitMessage(0);\r
233   }\r
234   return 0;\r
235 }\r