This source file includes following definitions.
- WinMain
- set_user_model_id
- ensure_unicows_dll
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #define DEFER_MS_W32_H
44 #include <config.h>
45
46 #include <windows.h>
47 #include <string.h>
48 #include <malloc.h>
49
50 static void set_user_model_id (void);
51 static int ensure_unicows_dll (void);
52
53 int WINAPI
54 WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow)
55 {
56 STARTUPINFO start;
57 SECURITY_ATTRIBUTES sec_attrs;
58 PROCESS_INFORMATION child;
59 int wait_for_child = FALSE;
60 DWORD priority_class = NORMAL_PRIORITY_CLASS;
61 DWORD ret_code = 0;
62 char *new_cmdline;
63 char *p;
64 char modname[MAX_PATH];
65 static const char iconic_opt[] = "--iconic ", maximized_opt[] = "--maximized ";
66
67 if (!ensure_unicows_dll ())
68 goto error;
69
70 set_user_model_id ();
71
72 if (!GetModuleFileName (NULL, modname, MAX_PATH))
73 goto error;
74 if ((p = strrchr (modname, '\\')) == NULL)
75 goto error;
76 *p = 0;
77
78 new_cmdline = alloca (MAX_PATH
79 + strlen (cmdline)
80 + ((nShow == SW_SHOWMINNOACTIVE
81 || nShow == SW_SHOWMAXIMIZED)
82 ? max (sizeof (iconic_opt), sizeof (maximized_opt))
83 : 0)
84 + 3);
85
86 *new_cmdline = '"';
87 strcpy (new_cmdline + 1, modname);
88
89
90 if ((p = strrchr (new_cmdline, '\\')) != NULL
91 && stricmp (p, "\\nt") == 0)
92 strcpy (p, "\\src");
93
94 #ifdef CHOOSE_NEWEST_EXE
95 {
96
97
98
99 char * best_name = alloca (MAX_PATH + 1);
100 FILETIME best_time = {0,0};
101 WIN32_FIND_DATA wfd;
102 HANDLE fh;
103 p = new_cmdline + strlen (new_cmdline);
104 strcpy (p, "\\emacs*.exe\" ");
105 fh = FindFirstFile (new_cmdline, &wfd);
106 if (fh == INVALID_HANDLE_VALUE)
107 goto error;
108 do
109 {
110 if (wfd.ftLastWriteTime.dwHighDateTime > best_time.dwHighDateTime
111 || (wfd.ftLastWriteTime.dwHighDateTime == best_time.dwHighDateTime
112 && wfd.ftLastWriteTime.dwLowDateTime > best_time.dwLowDateTime))
113 {
114 best_time = wfd.ftLastWriteTime;
115 strcpy (best_name, wfd.cFileName);
116 }
117 }
118 while (FindNextFile (fh, &wfd));
119 FindClose (fh);
120 *p++ = '\\';
121 strcpy (p, best_name);
122 strcat (p, " ");
123 }
124 #else
125 strcat (new_cmdline, "\\emacs.exe\" ");
126 #endif
127
128
129
130 while (cmdline[0] == '-' || cmdline[0] == '/')
131 {
132 if (strncmp (cmdline+1, "wait", 4) == 0)
133 {
134 wait_for_child = TRUE;
135 cmdline += 5;
136 }
137 else if (strncmp (cmdline+1, "high", 4) == 0)
138 {
139 priority_class = HIGH_PRIORITY_CLASS;
140 cmdline += 5;
141 }
142 else if (strncmp (cmdline+1, "low", 3) == 0)
143 {
144 priority_class = IDLE_PRIORITY_CLASS;
145 cmdline += 4;
146 }
147 else
148 break;
149
150 while (*++cmdline == ' ');
151 }
152
153
154
155
156
157 if (nShow == SW_SHOWMINNOACTIVE)
158 strcat (new_cmdline, iconic_opt);
159 else if (nShow == SW_SHOWMAXIMIZED)
160 strcat (new_cmdline, maximized_opt);
161 strcat (new_cmdline, cmdline);
162
163
164 if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
165 {
166 *p = 0;
167 for (p = modname; *p; p++)
168 if (*p == '\\') *p = '/';
169 SetEnvironmentVariable ("emacs_dir", modname);
170 }
171
172 memset (&start, 0, sizeof (start));
173 start.cb = sizeof (start);
174 start.dwFlags = STARTF_USESHOWWINDOW | STARTF_USECOUNTCHARS;
175 start.wShowWindow = SW_HIDE;
176
177
178 start.dwXCountChars = 80;
179 start.dwYCountChars = 25;
180
181 sec_attrs.nLength = sizeof (sec_attrs);
182 sec_attrs.lpSecurityDescriptor = NULL;
183 sec_attrs.bInheritHandle = FALSE;
184
185 if (CreateProcess (NULL, new_cmdline, &sec_attrs, NULL, TRUE, priority_class,
186 NULL, NULL, &start, &child))
187 {
188 if (wait_for_child)
189 {
190 WaitForSingleObject (child.hProcess, INFINITE);
191 GetExitCodeProcess (child.hProcess, &ret_code);
192 }
193 CloseHandle (child.hThread);
194 CloseHandle (child.hProcess);
195 }
196 else
197 goto error;
198 return (int) ret_code;
199
200 error:
201 MessageBox (NULL, "Could not start Emacs.", "Error", MB_ICONSTOP);
202 return 1;
203 }
204
205 void
206 set_user_model_id (void)
207 {
208 HMODULE shell;
209 HRESULT (WINAPI * set_user_model) (const wchar_t * id);
210
211
212
213
214 shell = LoadLibrary ("shell32.dll");
215 if (shell)
216 {
217 set_user_model
218 = (void *) GetProcAddress (shell,
219 "SetCurrentProcessExplicitAppUserModelID");
220
221
222
223
224
225
226 if (set_user_model)
227 set_user_model (L"GNU.Emacs");
228
229 FreeLibrary (shell);
230 }
231 }
232
233 static int
234 ensure_unicows_dll (void)
235 {
236 OSVERSIONINFO os_ver;
237 HMODULE h;
238
239 ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
240 os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
241 if (!GetVersionEx (&os_ver))
242 return 0;
243
244 if (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
245 {
246 h = LoadLibrary ("Unicows.dll");
247 if (!h)
248 {
249 int button;
250
251 button = MessageBox (NULL,
252 "Emacs cannot load the UNICOWS.DLL library.\n"
253 "This library is essential for using Emacs\n"
254 "on this system. You need to install it.\n\n"
255 "Emacs will exit when you click OK.",
256 "Emacs cannot load UNICOWS.DLL",
257 MB_ICONERROR | MB_TASKMODAL
258 | MB_SETFOREGROUND | MB_OK);
259 switch (button)
260 {
261 case IDOK:
262 default:
263 return 0;
264 }
265 }
266 FreeLibrary (h);
267 return 1;
268 }
269 return 1;
270 }