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

Diff of /trunk/Src/wptW32API.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.25  
changed lines
  Added in v.328

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26