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

Annotation of /trunk/Src/wptW32API.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 255 - (hide annotations)
Tue Aug 1 16:37:23 2006 UTC (18 years, 7 months ago) by twoaday
File size: 16149 byte(s)


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 twoaday 255 if (path && *path)
310     size += strlen (path);
311     if (file && *file)
312     size += strlen (file);
313 werner 36 if( ext && *ext )
314     size += strlen( ext );
315     p = new char[size + 4];
316 twoaday 255 if (!p)
317     BUG (0);
318 werner 36 memset( p, 0, size );
319     if( path ) {
320     strcat( p, path );
321     if( path[strlen( path ) -1] != '\\' )
322     strcat( p, "\\" );
323     }
324     if( file )
325     strcat( p, file );
326     if( ext ) {
327     strcat( p, "." );
328     strcat( p, ext );
329     }
330     return p;
331 twoaday 121 }
332 werner 36
333    
334 twoaday 150 /* Generate a file name from a special dirctory. */
335     char*
336     make_special_filename (int folder, const char *file, const char *ext)
337     {
338     BOOL ec;
339     char path[MAX_PATH], *p;
340     size_t n=0;
341    
342     /* MSDN: buf must be at least MAX_PATH=256 bytes */
343     ec = SHGetSpecialFolderPath (HWND_DESKTOP, path, folder, TRUE);
344     if (ec != 1) {
345     log_debug ("SHGetSpecialFolderPath() failed\r\n", (int)GetLastError ());
346     return NULL;
347     }
348    
349     n = strlen (path)+1;
350     if (file)
351     n += strlen (file)+1;
352     if (ext)
353     n += strlen (ext)+1;
354     p = new char[n+2];
355     if (!p)
356     BUG (0);
357     memset (p, 0, n+2);
358     strcpy (p, path);
359     if (file) {
360     strcat (p, "\\");
361     strcat (p, file);
362     }
363     if (ext)
364     strcat (p, ext);
365     return p;
366     }
367    
368    
369 twoaday 121 /* return 0 if the file @fname exists, otherwise >0. */
370 werner 36 int
371 twoaday 121 file_exist_check (const char *fname)
372 werner 36 {
373     struct stat st;
374     if (stat (fname, &st) == -1)
375     return WPTERR_FILE_EXIST;
376     return 0;
377     }
378    
379    
380     /* Check if the current folder exists.
381     Return 0 for success. */
382     int
383     dir_exist_check (const char *dir)
384     {
385     struct stat statbuf;
386    
387 twoaday 105 if (stat (dir, &statbuf) == -1)
388 werner 36 return WPTERR_GENERAL;
389 twoaday 105 if (statbuf.st_mode & _S_IFDIR)
390 werner 36 return 0;
391     return WPTERR_GENERAL;
392     }
393    
394    
395 twoaday 77 /* Return the file size of the given file @fname. */
396     DWORD
397 werner 36 get_file_size (const char *fname)
398     {
399 twoaday 77 DWORD fsize;
400 werner 36 HANDLE fh;
401    
402 twoaday 77 fh = CreateFile (fname, GENERIC_READ, FILE_SHARE_READ,
403     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
404     if (fh == INVALID_HANDLE_VALUE)
405 werner 36 return 0;
406 twoaday 77 fsize = GetFileSize (fh, NULL);
407     if (fsize == 0xFFFFFFFF)
408 werner 36 fsize = 0;
409 twoaday 77 CloseHandle (fh);
410 werner 36 return fsize;
411 twoaday 77 }
412 werner 36
413    
414     /* Start a dialog with the exception that before it is checked that the
415     dialog is not already openened. */
416     int
417 twoaday 105 dialog_box_param (HINSTANCE hinst, LPCTSTR name, HWND parent, DLGPROC fnc,
418     LPARAM param, LPCTSTR title, int title_id)
419 werner 36 {
420 twoaday 105 if (FindWindowEx (GetDesktopWindow (), NULL, NULL, title))
421 werner 36 return -1;
422 twoaday 105 return DialogBoxParam (hinst, name, parent, fnc, param);
423     }
424 werner 36
425    
426     /* Wrapper for message box which forces the message box into the
427     foreground and it is displayed always on top. */
428     int
429     msg_box (HWND hwnd, const char *text, const char *title, int mode)
430     {
431     mode |= MB_SETFOREGROUND;
432     mode |= MB_TASKMODAL;
433     mode |= MB_TOPMOST;
434     return MessageBox(hwnd, text, title, mode);
435     }
436    
437    
438 twoaday 121 /* Safe strdup version (C++ version). */
439 werner 36 char*
440     m_strdup (const char *str)
441     {
442 twoaday 121 char *p = new char[strlen (str) + 1];
443     if (!p)
444     BUG (NULL);
445     strcpy (p, str);
446 werner 36 return p;
447 twoaday 121 }
448 werner 36
449    
450     /* Center the hwndChild relative to parent.
451     The style param allows to specificy additional styles (like topmost). */
452     void
453     center_window2 (HWND hwndChild, HWND parent, HWND style)
454     {
455     HWND hwndParent;
456     RECT rChild, rParent;
457     HDC hdc;
458     int wChild, hChild, wParent, hParent;
459     int wScreen, hScreen, xNew, yNew;
460     int flags = SWP_NOSIZE | SWP_NOZORDER;
461    
462     hwndParent = parent;
463     if (hwndParent == NULL)
464     hwndParent = GetDesktopWindow ();
465     GetWindowRect (hwndChild, &rChild);
466     wChild = rChild.right - rChild.left;
467     hChild = rChild.bottom - rChild.top;
468    
469     GetWindowRect (hwndParent, &rParent);
470     wParent = rParent.right - rParent.left;
471     hParent = rParent.bottom - rParent.top;
472    
473     hdc = GetDC (hwndChild);
474     wScreen = GetDeviceCaps (hdc, HORZRES);
475     hScreen = GetDeviceCaps (hdc, VERTRES);
476     ReleaseDC (hwndChild, hdc);
477     xNew = rParent.left + ((wParent - wChild) /2);
478     if (xNew < 0)
479     xNew = 0;
480     else if ((xNew+wChild) > wScreen)
481     xNew = wScreen - wChild;
482     yNew = rParent.top + ((hParent - hChild) /2);
483     if (yNew < 0)
484     yNew = 0;
485     else if ((yNew+hChild) > hScreen)
486     yNew = hScreen - hChild;
487     if (style == HWND_TOPMOST || style == HWND_NOTOPMOST)
488     flags = SWP_NOMOVE | SWP_NOSIZE;
489     SetWindowPos (hwndChild, style? style : NULL, xNew, yNew, 0, 0, flags);
490     }
491    
492    
493     /* Center the given hwndChild window with no special style. */
494     void
495     center_window (HWND hwndChild, HWND hwndParent)
496     {
497     center_window2 (hwndChild, hwndParent, NULL);
498     }
499 twoaday 121
500    
501     /* Retrieve the product verion of the given file @fname.
502     Format: MAJOR.MINOR.PATCH1.PATCH2
503     Return value: 0 on success. */
504     int
505     get_file_version (const char *fname, WORD *major, WORD *minor,
506     WORD *patch1, WORD *patch2)
507     {
508 twoaday 248 VS_FIXEDFILEINFO *inf;
509 twoaday 121 char file[MAX_PATH+1] = {0};
510     LPVOID buf, data;
511     DWORD arg;
512     DWORD size;
513     UINT qlen;
514    
515     strncpy (file, fname, MAX_PATH);
516     size = GetFileVersionInfoSize (file, &arg);
517     if (!size)
518     return -1;
519 twoaday 248 buf = (LPVOID)new char[size];
520 twoaday 121 if (!buf)
521     BUG (NULL);
522     GetFileVersionInfo (file, 0, size, buf);
523    
524     qlen=0;
525     VerQueryValue (buf, "\\", &data, &qlen);
526     if (!qlen) {
527 twoaday 248 delete [](char*)buf;
528 twoaday 121 return -1;
529     }
530     inf = (VS_FIXEDFILEINFO*)data;
531    
532     if (major)
533     *major = HIWORD (inf->dwProductVersionMS);
534     if (minor)
535     *minor = LOWORD (inf->dwProductVersionMS);
536     if (patch1)
537     *patch1 = HIWORD (inf->dwProductVersionLS);
538     if (patch2)
539     *patch2 = LOWORD (inf->dwProductVersionLS);
540    
541 twoaday 248 delete [](char*)buf;
542 twoaday 121 return 0;
543     }
544    
545    
546 twoaday 129 /* Return date in a format which complies with the
547     system locale settings. */
548     const char*
549     get_locale_date (long tm_t, char *buf, DWORD buflen)
550     {
551     SYSTEMTIME st;
552     struct tm *ptm;
553 twoaday 121
554 twoaday 129 ptm = localtime (&tm_t);
555     st.wYear = (WORD)ptm->tm_year;
556     st.wMonth = (WORD)ptm->tm_mon;
557     st.wDay = (WORD)ptm->tm_mday;
558     st.wYear += 1900;
559     st.wMonth += 1;
560     if (!GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,
561     NULL, buf, buflen))
562     return NULL;
563     return buf;
564     }
565 twoaday 121
566    
567 twoaday 175 /* Generate a temporary file name by using the users
568     temp path and optionally a name @name provided by the caller.
569     Return value: 0 on success. */
570     int
571     get_temp_name (char *buf, DWORD buflen, const char *name)
572     {
573     char tmp[32];
574    
575     if (!name) {
576     sprintf (tmp, "%08lX", GetTickCount ());
577     name = tmp;
578     }
579 twoaday 190
580     /* in the mobile mode we use a local temp folder
581     with the fixed name 'temp'. */
582     if (mobile_mode_active) {
583     _snprintf (buf, buflen-1, "temp\\%s", name);
584     return 0;
585     }
586    
587 twoaday 175 if (!GetTempPath (buflen - strlen (name) -2, buf)) {
588     log_debug ("GetTempPath() failed ec=%d\n", (int)GetLastError ());
589     return -1;
590     }
591     strcat (buf, name);
592     return 0;
593     }
594    
595    
596 twoaday 204 void
597     ListBox_AddString_utf8 (HWND lb, const char *txt)
598     {
599     char *utf8_txt;
600    
601     utf8_txt = utf8_to_native (txt);
602     SendMessage (lb, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
603     safe_free (utf8_txt);
604     }
605    
606    
607     void
608     ComboBox_AddString_utf8 (HWND cb, const char *txt)
609     {
610    
611     char *utf8_txt;
612    
613     utf8_txt = utf8_to_native (txt);
614     SendMessage ((cb), CB_ADDSTRING, 0, (LPARAM)(LPCSTR)(utf8_txt));
615     safe_free (utf8_txt);
616     }
617    
618    
619     /* GetDlgItemText replacement with UTF8 support. */
620     int
621     GetDlgItemText_utf8 (HWND dlg, int id, char **r_txt)
622     {
623     int len = GetWindowTextLength (GetDlgItem (dlg, id));
624     char *txt;
625    
626     *r_txt = NULL;
627     if (len < 1)
628     return 0;
629     txt = new char[len+2];
630     if (!txt)
631     BUG (NULL);
632     GetDlgItemText (dlg, id, txt, len+1);
633     *r_txt = native_to_utf8 (txt);
634     free_if_alloc (txt);
635     return len;
636     }
637    
638    
639 twoaday 208 /* Return TRUE if the current user has admin privileges. */
640     BOOL
641     user_is_admin (void)
642     {
643     SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
644 twoaday 129 HANDLE hd;
645 twoaday 208 TOKEN_GROUPS *ptg = NULL;
646     DWORD ngtoken;
647     DWORD i;
648     BOOL admin = FALSE;
649     PSID psid = 0;
650 twoaday 121
651 twoaday 208 if (GetVersion () & 0x80000000) /* Win9X */
652     return TRUE;
653 twoaday 121
654 twoaday 208 if (!OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, FALSE, &hd) &&
655     !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &hd))
656     return FALSE;
657    
658     if (!GetTokenInformation (hd, TokenGroups, NULL, 0, &ngtoken) &&
659     GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
660     ptg = (TOKEN_GROUPS*)GlobalAlloc (GPTR, ngtoken);
661     if (!ptg)
662     return FALSE;
663 twoaday 121
664 twoaday 208 if (!GetTokenInformation (hd, TokenGroups,
665     ptg, ngtoken, &ngtoken)) {
666     GlobalFree (ptg);
667     return FALSE;
668     }
669     AllocateAndInitializeSid (&SystemSidAuthority,
670     2, SECURITY_BUILTIN_DOMAIN_RID,
671     DOMAIN_ALIAS_RID_ADMINS,
672     0, 0, 0, 0, 0, 0,
673     &psid);
674     for (i = 0; i < ptg->GroupCount; i++) {
675     if (EqualSid (ptg->Groups[i].Sid, psid)) {
676     admin = TRUE;
677     break;
678     }
679     }
680     FreeSid (psid);
681     GlobalFree (ptg);
682     }
683 twoaday 121
684 twoaday 208 CloseHandle (hd);
685     return admin;
686 twoaday 129 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26