/[winpt]/trunk/Src/wptW32API.cpp
ViewVC logotype

Annotation of /trunk/Src/wptW32API.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 248 - (hide annotations)
Fri Jul 28 11:11:09 2006 UTC (18 years, 7 months ago) by twoaday
File size: 16131 byte(s)
Prepare 1.0.0pre2 release.


1 werner 36 /* wptW32API.cpp - Common W32 API functions
2 twoaday 121 * Copyright (C) 2001, 2002, 2003, 2005 Timo Schulz
3 werner 36 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20 twoaday 121
21 werner 36 #ifdef HAVE_CONFIG_H
22     #include <config.h>
23     #endif
24    
25     #include <windows.h>
26     #include <stdio.h>
27     #include <sys/types.h>
28     #include <sys/stat.h>
29     #include <shellapi.h>
30     #include <shlobj.h>
31     #include <commctrl.h>
32 twoaday 129 #include <time.h>
33 werner 36
34     #include "wptNLS.h"
35     #include "wptW32API.h"
36     #include "wptErrors.h"
37     #include "wptVersion.h"
38 twoaday 204 #include "wptUTF8.h"
39 werner 36 #include "wptTypes.h"
40    
41    
42     extern "C" void _SHFree (void *p);
43    
44    
45 twoaday 193
46     /* Insert a new item into the menu @hm at position @pos. */
47     void
48     insert_menu_item (HMENU hm, int pos, UINT m_id, const char *text)
49     {
50     MENUITEMINFO mi;
51    
52     memset (&mi, 0, sizeof mi);
53     mi.cbSize = sizeof mi;
54     mi.fType = MF_STRING;
55     mi.dwTypeData = (char *)text;
56     mi.cch = strlen (text);
57     mi.wID = m_id;
58     mi.fMask = MIIM_ID|MIIM_DATA| MIIM_TYPE;
59     InsertMenuItem (hm, pos, FALSE, &mi);
60     }
61    
62    
63 werner 36 static void
64     set_menu_text_ext (HMENU menu, int by_pos, int m_uid, const char *text)
65     {
66     MENUITEMINFO mii;
67    
68     memset (&mii, 0, sizeof mii);
69     mii.cbSize = sizeof mii;
70     mii.fMask = MIIM_TYPE;
71     mii.fType = MFT_STRING;
72     mii.dwTypeData = (char *) text;
73     SetMenuItemInfo (menu, m_uid, by_pos? TRUE : FALSE, &mii);
74     }
75    
76    
77     /* Set the text of a menu item @m_uid to @text. */
78     void
79 twoaday 129 set_menu_text (HMENU menu, UINT m_uid, const char *text)
80 werner 36 {
81     set_menu_text_ext (menu, 0, m_uid, text);
82     }
83    
84    
85     /* Set the text of a menu item with the position @pos to @text. */
86     void
87 twoaday 129 set_menu_text_bypos (HMENU menu, UINT pos, const char *text)
88 werner 36 {
89     set_menu_text_ext (menu, 1, pos, text);
90     }
91    
92    
93     /* Set the state of a menu item @m_uid to @state. */
94     void
95 twoaday 129 set_menu_state (HMENU menu, UINT m_uid, UINT state)
96 werner 36 {
97     MENUITEMINFO mii;
98    
99 twoaday 121 memset (&mii, 0, sizeof (mii));
100 werner 36 mii.cbSize = sizeof (mii);
101     mii.fMask = MIIM_STATE;
102     mii.fState = state;
103     SetMenuItemInfo (menu, m_uid, FALSE, &mii);
104     }
105    
106    
107 twoaday 129 /* Retrieve the state of the menu item @m_uid and return it. */
108     UINT
109     get_menu_state (HMENU menu, UINT m_uid)
110     {
111     MENUITEMINFO mii;
112    
113     memset (&mii, 0, sizeof (mii));
114     mii.cbSize = sizeof (mii);
115     mii.fMask = MIIM_STATE;
116     GetMenuItemInfo (menu, m_uid, FALSE, &mii);
117     return mii.fState;
118     }
119    
120    
121 twoaday 77 enum {
122     CDLG_FILE_OPEN = 0,
123     CDLG_FILE_SAVE = 1
124     };
125 werner 36
126     /* Use the common dialog to request a file from the user.
127     id can be either FILE_OPEN or FILE_SAVE.
128     The return value is the file name or NULL if cancel was chosen. */
129     const char *
130 twoaday 193 get_filename_dlg (HWND hwnd, int id, const char *title,
131     const char *filter, const char *name)
132 werner 36 {
133     static char file[512] = "";
134     OPENFILENAME open;
135    
136     if (name && strlen (name) < (sizeof (file)-1))
137     strcpy (file, name);
138     else
139     memset (file, 0, sizeof (file));
140     if (!filter)
141 twoaday 167 filter = "All Files (*.*)\0*.*\0\0";
142 werner 36 /* XXX: problem with gettext because of the 'artificial'
143     double string termination!. */
144     memset (&open, 0, sizeof (open));
145     open.lStructSize = sizeof (OPENFILENAME);
146     open.hInstance = glob_hinst;
147     open.lpstrTitle = title;
148     open.lpstrFilter = filter;
149     open.hwndOwner = hwnd;
150     open.lpstrFile = file;
151     open.nMaxFile = sizeof (file) - 1;
152 twoaday 77 if (id == CDLG_FILE_OPEN)
153 werner 36 open.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
154     else
155     open.Flags = OFN_OVERWRITEPROMPT;
156    
157 twoaday 77 if (id == CDLG_FILE_OPEN && GetOpenFileName (&open))
158 werner 36 return open.lpstrFile;
159 twoaday 77 else if (id == CDLG_FILE_SAVE && GetSaveFileName (&open))
160 werner 36 return open.lpstrFile;
161    
162     return NULL;
163     }
164    
165     const char*
166     get_filesave_dlg (HWND hwnd, const char *title,
167     const char *filter, const char *name)
168     {
169 twoaday 77 return get_filename_dlg (hwnd, CDLG_FILE_SAVE, title, filter, name);
170 werner 36 }
171    
172 twoaday 121 const char*
173 werner 36 get_fileopen_dlg (HWND hwnd, const char *title, const char *filter,
174     const char *name)
175     {
176 twoaday 77 return get_filename_dlg (hwnd, CDLG_FILE_OPEN, title, filter, name);
177 werner 36 }
178    
179    
180     /* Use the common dialog to allow the user to select a folder.
181     The return value is either the folder path or NULL if cancel was chosen. */
182     const char*
183 twoaday 121 get_folder_dlg (HWND hwnd, const char *title, const char *name)
184 werner 36 {
185     static char folder[MAX_PATH+1] = "";
186     BROWSEINFO bi;
187 twoaday 121 ITEMIDLIST *il;
188 werner 36
189     memset (&bi, 0, sizeof (bi));
190     bi.hwndOwner = hwnd;
191     if (title)
192     bi.lpszTitle = title;
193     if (name && strlen (name) < MAX_PATH-1)
194     strcpy (folder, name);
195     else
196     memset (folder, 0, sizeof (folder));
197     il = SHBrowseForFolder (&bi);
198     if (il) {
199     SHGetPathFromIDList (il, folder);
200     _SHFree (il);
201     return folder;
202     }
203     return NULL;
204     }
205    
206    
207     /* Return the clipboard contents as a string or NULL
208     if the clipboard does not contain text. */
209     char*
210     get_clip_text (HWND hwnd)
211     {
212     HANDLE clipmem;
213     char *cliptxt, *p;
214     int len;
215    
216     if (OpenClipboard (hwnd) == FALSE)
217     return NULL;
218     clipmem = GetClipboardData (CF_TEXT);
219     if (clipmem == NULL) {
220     p = NULL;
221     goto leave;
222     }
223     cliptxt = (char *) GlobalLock (clipmem);
224     if (cliptxt == NULL) {
225     p = NULL;
226     goto leave;
227     }
228    
229     len = strlen (cliptxt);
230     p = new char[len + 1];
231     if (!p)
232     BUG (NULL);
233     memcpy (p, cliptxt, len);
234     p[len] = '\0';
235     GlobalUnlock (clipmem);
236    
237     leave:
238     CloseClipboard ();
239     return p;
240     }
241    
242    
243     /* Set @text as the new clipboard content. */
244     int
245     set_clip_text (HWND hwnd, const char *text, int nbytes)
246     {
247     HANDLE clipmem;
248     int rc = 0;
249     char *p;
250    
251     if (OpenClipboard (hwnd) == FALSE)
252     return WPTERR_CLIP_OPEN;
253     EmptyClipboard ();
254    
255     clipmem = GlobalAlloc (GHND, nbytes + 1);
256     if (clipmem == NULL)
257     BUG (NULL);
258     p = (char *) GlobalLock (clipmem);
259     if (p == NULL) {
260 twoaday 196 CloseClipboard ();
261     GlobalFree (clipmem);
262     return WPTERR_GENERAL;
263 werner 36 }
264     memcpy (p, text, nbytes);
265     p[nbytes] = '\0';
266    
267 twoaday 196 SetClipboardData (CF_TEXT, clipmem);
268 werner 36 GlobalUnlock (clipmem);
269 twoaday 196 CloseClipboard ();
270 twoaday 181 GlobalFree (clipmem);
271 werner 36
272     return rc;
273 twoaday 181 }
274 werner 36
275    
276     /* Append or prepend some text to the clipboard contents.
277     If as_footer = 1, append the text otherwise prepend. */
278     int
279     set_clip_text2 (HWND hwnd, const char *text, int nbytes, int as_footer)
280     {
281     char *p, *new_text;
282    
283     p = get_clip_text (hwnd);
284     if (!p)
285     return WPTERR_CLIP_GET;
286     new_text = new char [strlen (p)+strlen (text)+8];
287     if (!new_text)
288     BUG (0);
289     if (as_footer == 0)
290     sprintf (new_text, "%s\r\n%s\r\n\r\n", text, p);
291     else
292     sprintf (new_text, "%s\n%s\n\n", p, text);
293     set_clip_text (hwnd, new_text, strlen (new_text)+1);
294     free_if_alloc (p);
295     free_if_alloc (new_text);
296     return 0;
297     }
298    
299    
300 twoaday 121 /* Make a file name out of the path @path, the file @file and
301     an extension. @ext.
302     Return value: the full file name on success. */
303 werner 36 char*
304     make_filename (const char *path, const char *file, const char *ext)
305     {
306     char *p;
307     size_t size = 0;
308    
309     if( path && *path )
310     size += strlen( path );
311     if( file && *file )
312     size += strlen( file );
313     if( ext && *ext )
314     size += strlen( ext );
315     p = new char[size + 4];
316     memset( p, 0, size );
317     if( path ) {
318     strcat( p, path );
319     if( path[strlen( path ) -1] != '\\' )
320     strcat( p, "\\" );
321     }
322     if( file )
323     strcat( p, file );
324     if( ext ) {
325     strcat( p, "." );
326     strcat( p, ext );
327     }
328     return p;
329 twoaday 121 }
330 werner 36
331    
332 twoaday 150 /* Generate a file name from a special dirctory. */
333     char*
334     make_special_filename (int folder, const char *file, const char *ext)
335     {
336     BOOL ec;
337     char path[MAX_PATH], *p;
338     size_t n=0;
339    
340     /* MSDN: buf must be at least MAX_PATH=256 bytes */
341     ec = SHGetSpecialFolderPath (HWND_DESKTOP, path, folder, TRUE);
342     if (ec != 1) {
343     log_debug ("SHGetSpecialFolderPath() failed\r\n", (int)GetLastError ());
344     return NULL;
345     }
346    
347     n = strlen (path)+1;
348     if (file)
349     n += strlen (file)+1;
350     if (ext)
351     n += strlen (ext)+1;
352     p = new char[n+2];
353     if (!p)
354     BUG (0);
355     memset (p, 0, n+2);
356     strcpy (p, path);
357     if (file) {
358     strcat (p, "\\");
359     strcat (p, file);
360     }
361     if (ext)
362     strcat (p, ext);
363     return p;
364     }
365    
366    
367 twoaday 121 /* return 0 if the file @fname exists, otherwise >0. */
368 werner 36 int
369 twoaday 121 file_exist_check (const char *fname)
370 werner 36 {
371     struct stat st;
372     if (stat (fname, &st) == -1)
373     return WPTERR_FILE_EXIST;
374     return 0;
375     }
376    
377    
378     /* Check if the current folder exists.
379     Return 0 for success. */
380     int
381     dir_exist_check (const char *dir)
382     {
383     struct stat statbuf;
384    
385 twoaday 105 if (stat (dir, &statbuf) == -1)
386 werner 36 return WPTERR_GENERAL;
387 twoaday 105 if (statbuf.st_mode & _S_IFDIR)
388 werner 36 return 0;
389     return WPTERR_GENERAL;
390     }
391    
392    
393 twoaday 77 /* Return the file size of the given file @fname. */
394     DWORD
395 werner 36 get_file_size (const char *fname)
396     {
397 twoaday 77 DWORD fsize;
398 werner 36 HANDLE fh;
399    
400 twoaday 77 fh = CreateFile (fname, GENERIC_READ, FILE_SHARE_READ,
401     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
402     if (fh == INVALID_HANDLE_VALUE)
403 werner 36 return 0;
404 twoaday 77 fsize = GetFileSize (fh, NULL);
405     if (fsize == 0xFFFFFFFF)
406 werner 36 fsize = 0;
407 twoaday 77 CloseHandle (fh);
408 werner 36 return fsize;
409 twoaday 77 }
410 werner 36
411    
412     /* Start a dialog with the exception that before it is checked that the
413     dialog is not already openened. */
414     int
415 twoaday 105 dialog_box_param (HINSTANCE hinst, LPCTSTR name, HWND parent, DLGPROC fnc,
416     LPARAM param, LPCTSTR title, int title_id)
417 werner 36 {
418 twoaday 105 if (FindWindowEx (GetDesktopWindow (), NULL, NULL, title))
419 werner 36 return -1;
420 twoaday 105 return DialogBoxParam (hinst, name, parent, fnc, param);
421     }
422 werner 36
423    
424     /* Wrapper for message box which forces the message box into the
425     foreground and it is displayed always on top. */
426     int
427     msg_box (HWND hwnd, const char *text, const char *title, int mode)
428     {
429     mode |= MB_SETFOREGROUND;
430     mode |= MB_TASKMODAL;
431     mode |= MB_TOPMOST;
432     return MessageBox(hwnd, text, title, mode);
433     }
434    
435    
436 twoaday 121 /* Safe strdup version (C++ version). */
437 werner 36 char*
438     m_strdup (const char *str)
439     {
440 twoaday 121 char *p = new char[strlen (str) + 1];
441     if (!p)
442     BUG (NULL);
443     strcpy (p, str);
444 werner 36 return p;
445 twoaday 121 }
446 werner 36
447    
448     /* Center the hwndChild relative to parent.
449     The style param allows to specificy additional styles (like topmost). */
450     void
451     center_window2 (HWND hwndChild, HWND parent, HWND style)
452     {
453     HWND hwndParent;
454     RECT rChild, rParent;
455     HDC hdc;
456     int wChild, hChild, wParent, hParent;
457     int wScreen, hScreen, xNew, yNew;
458     int flags = SWP_NOSIZE | SWP_NOZORDER;
459    
460     hwndParent = parent;
461     if (hwndParent == NULL)
462     hwndParent = GetDesktopWindow ();
463     GetWindowRect (hwndChild, &rChild);
464     wChild = rChild.right - rChild.left;
465     hChild = rChild.bottom - rChild.top;
466    
467     GetWindowRect (hwndParent, &rParent);
468     wParent = rParent.right - rParent.left;
469     hParent = rParent.bottom - rParent.top;
470    
471     hdc = GetDC (hwndChild);
472     wScreen = GetDeviceCaps (hdc, HORZRES);
473     hScreen = GetDeviceCaps (hdc, VERTRES);
474     ReleaseDC (hwndChild, hdc);
475     xNew = rParent.left + ((wParent - wChild) /2);
476     if (xNew < 0)
477     xNew = 0;
478     else if ((xNew+wChild) > wScreen)
479     xNew = wScreen - wChild;
480     yNew = rParent.top + ((hParent - hChild) /2);
481     if (yNew < 0)
482     yNew = 0;
483     else if ((yNew+hChild) > hScreen)
484     yNew = hScreen - hChild;
485     if (style == HWND_TOPMOST || style == HWND_NOTOPMOST)
486     flags = SWP_NOMOVE | SWP_NOSIZE;
487     SetWindowPos (hwndChild, style? style : NULL, xNew, yNew, 0, 0, flags);
488     }
489    
490    
491     /* Center the given hwndChild window with no special style. */
492     void
493     center_window (HWND hwndChild, HWND hwndParent)
494     {
495     center_window2 (hwndChild, hwndParent, NULL);
496     }
497 twoaday 121
498    
499     /* Retrieve the product verion of the given file @fname.
500     Format: MAJOR.MINOR.PATCH1.PATCH2
501     Return value: 0 on success. */
502     int
503     get_file_version (const char *fname, WORD *major, WORD *minor,
504     WORD *patch1, WORD *patch2)
505     {
506 twoaday 248 VS_FIXEDFILEINFO *inf;
507 twoaday 121 char file[MAX_PATH+1] = {0};
508     LPVOID buf, data;
509     DWORD arg;
510     DWORD size;
511     UINT qlen;
512    
513     strncpy (file, fname, MAX_PATH);
514     size = GetFileVersionInfoSize (file, &arg);
515     if (!size)
516     return -1;
517 twoaday 248 buf = (LPVOID)new char[size];
518 twoaday 121 if (!buf)
519     BUG (NULL);
520     GetFileVersionInfo (file, 0, size, buf);
521    
522     qlen=0;
523     VerQueryValue (buf, "\\", &data, &qlen);
524     if (!qlen) {
525 twoaday 248 delete [](char*)buf;
526 twoaday 121 return -1;
527     }
528     inf = (VS_FIXEDFILEINFO*)data;
529    
530     if (major)
531     *major = HIWORD (inf->dwProductVersionMS);
532     if (minor)
533     *minor = LOWORD (inf->dwProductVersionMS);
534     if (patch1)
535     *patch1 = HIWORD (inf->dwProductVersionLS);
536     if (patch2)
537     *patch2 = LOWORD (inf->dwProductVersionLS);
538    
539 twoaday 248 delete [](char*)buf;
540 twoaday 121 return 0;
541     }
542    
543    
544 twoaday 129 /* Return date in a format which complies with the
545     system locale settings. */
546     const char*
547     get_locale_date (long tm_t, char *buf, DWORD buflen)
548     {
549     SYSTEMTIME st;
550     struct tm *ptm;
551 twoaday 121
552 twoaday 129 ptm = localtime (&tm_t);
553     st.wYear = (WORD)ptm->tm_year;
554     st.wMonth = (WORD)ptm->tm_mon;
555     st.wDay = (WORD)ptm->tm_mday;
556     st.wYear += 1900;
557     st.wMonth += 1;
558     if (!GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,
559     NULL, buf, buflen))
560     return NULL;
561     return buf;
562     }
563 twoaday 121
564    
565 twoaday 175 /* Generate a temporary file name by using the users
566     temp path and optionally a name @name provided by the caller.
567     Return value: 0 on success. */
568     int
569     get_temp_name (char *buf, DWORD buflen, const char *name)
570     {
571     char tmp[32];
572    
573     if (!name) {
574     sprintf (tmp, "%08lX", GetTickCount ());
575     name = tmp;
576     }
577 twoaday 190
578     /* in the mobile mode we use a local temp folder
579     with the fixed name 'temp'. */
580     if (mobile_mode_active) {
581     _snprintf (buf, buflen-1, "temp\\%s", name);
582     return 0;
583     }
584    
585 twoaday 175 if (!GetTempPath (buflen - strlen (name) -2, buf)) {
586     log_debug ("GetTempPath() failed ec=%d\n", (int)GetLastError ());
587     return -1;
588     }
589     strcat (buf, name);
590     return 0;
591     }
592    
593    
594 twoaday 204 void
595     ListBox_AddString_utf8 (HWND lb, const char *txt)
596     {
597     char *utf8_txt;
598    
599     utf8_txt = utf8_to_native (txt);
600     SendMessage (lb, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
601     safe_free (utf8_txt);
602     }
603    
604    
605     void
606     ComboBox_AddString_utf8 (HWND cb, const char *txt)
607     {
608    
609     char *utf8_txt;
610    
611     utf8_txt = utf8_to_native (txt);
612     SendMessage ((cb), CB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
613     safe_free (utf8_txt);
614     }
615    
616    
617     /* GetDlgItemText replacement with UTF8 support. */
618     int
619     GetDlgItemText_utf8 (HWND dlg, int id, char **r_txt)
620     {
621     int len = GetWindowTextLength (GetDlgItem (dlg, id));
622     char *txt;
623    
624     *r_txt = NULL;
625     if (len < 1)
626     return 0;
627     txt = new char[len+2];
628     if (!txt)
629     BUG (NULL);
630     GetDlgItemText (dlg, id, txt, len+1);
631     *r_txt = native_to_utf8 (txt);
632     free_if_alloc (txt);
633     return len;
634     }
635    
636    
637 twoaday 208 /* Return TRUE if the current user has admin privileges. */
638     BOOL
639     user_is_admin (void)
640     {
641     SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
642 twoaday 129 HANDLE hd;
643 twoaday 208 TOKEN_GROUPS *ptg = NULL;
644     DWORD ngtoken;
645     DWORD i;
646     BOOL admin = FALSE;
647     PSID psid = 0;
648 twoaday 121
649 twoaday 208 if (GetVersion () & 0x80000000) /* Win9X */
650     return TRUE;
651 twoaday 121
652 twoaday 208 if (!OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, FALSE, &hd) &&
653     !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &hd))
654     return FALSE;
655    
656     if (!GetTokenInformation (hd, TokenGroups, NULL, 0, &ngtoken) &&
657     GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
658     ptg = (TOKEN_GROUPS*)GlobalAlloc (GPTR, ngtoken);
659     if (!ptg)
660     return FALSE;
661 twoaday 121
662 twoaday 208 if (!GetTokenInformation (hd, TokenGroups,
663     ptg, ngtoken, &ngtoken)) {
664     GlobalFree (ptg);
665     return FALSE;
666     }
667     AllocateAndInitializeSid (&SystemSidAuthority,
668     2, SECURITY_BUILTIN_DOMAIN_RID,
669     DOMAIN_ALIAS_RID_ADMINS,
670     0, 0, 0, 0, 0, 0,
671     &psid);
672     for (i = 0; i < ptg->GroupCount; i++) {
673     if (EqualSid (ptg->Groups[i].Sid, psid)) {
674     admin = TRUE;
675     break;
676     }
677     }
678     FreeSid (psid);
679     GlobalFree (ptg);
680     }
681 twoaday 121
682 twoaday 208 CloseHandle (hd);
683     return admin;
684 twoaday 129 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26