/[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 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 167 by twoaday, Thu Jan 26 10:17:17 2006 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, 2002, 2003, 2005 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   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
20    
21  #include <windows.h>  #ifdef HAVE_CONFIG_H
22  #include <stdio.h>  #include <config.h>
23  #include <sys/types.h>  #endif
24  #include <sys/stat.h>  
25  #include <shellapi.h>  #include <windows.h>
26  #include <shlobj.h>  #include <stdio.h>
27  #include <commctrl.h>  #include <sys/types.h>
28    #include <sys/stat.h>
29  #include "wptNLS.h"  #include <shellapi.h>
30  #include "wptW32API.h"  #include <shlobj.h>
31  #include "wptErrors.h"  #include <commctrl.h>
32  #include "wptVersion.h"  #include <time.h>
33  #include "wptTypes.h"  
34    #include "wptNLS.h"
35    #include "wptW32API.h"
36  extern "C" void _SHFree (void *p);  #include "wptErrors.h"
37    #include "wptVersion.h"
38  /* The the text of a menu item. */  #include "wptTypes.h"
39  void  
40  set_menu_text (HMENU menu, int m_uid, const char *text)  
41  {  extern "C" void _SHFree (void *p);
42      MENUITEMINFO mii;  
43      char menu_text[80];  
44        static void
45      memset (&mii, 0, sizeof (mii));  set_menu_text_ext (HMENU menu, int by_pos, int m_uid, const char *text)
46      mii.cbSize = sizeof (mii);  {
47      mii.fMask = MIIM_TYPE;      MENUITEMINFO mii;
48      mii.dwTypeData = menu_text;      
49      mii.cch = sizeof (menu_text);      memset (&mii, 0, sizeof mii);
50      GetMenuItemInfo (menu, m_uid, FALSE, &mii);      mii.cbSize = sizeof mii;
51            mii.fMask = MIIM_TYPE;
52      memset (&mii, 0, sizeof mii);      mii.fType = MFT_STRING;
53      mii.cbSize = sizeof mii;      mii.dwTypeData = (char *) text;
54      mii.fMask = MIIM_TYPE;      SetMenuItemInfo (menu, m_uid, by_pos? TRUE : FALSE, &mii);
55      mii.fType = MFT_STRING;  }
56      mii.dwTypeData = (char *) text;  
57      SetMenuItemInfo (menu, m_uid, FALSE, &mii);  
58  } /* set_menu_text */  /* Set the text of a menu item @m_uid to @text. */
59    void
60    set_menu_text (HMENU menu, UINT m_uid, const char *text)
61  void  {
62  set_menu_state (HMENU menu, int m_uid, int state)      set_menu_text_ext (menu, 0, m_uid, text);
63  {        }
64      MENUITEMINFO mii;  
65    
66      memset( &mii, 0, sizeof (mii) );  /* Set the text of a menu item with the position @pos to @text. */
67      mii.cbSize = sizeof (mii);  void
68      mii.fMask = MIIM_STATE;  set_menu_text_bypos (HMENU menu, UINT pos, const char *text)
69      mii.fState = state;  {
70      SetMenuItemInfo (menu, m_uid, FALSE, &mii);      set_menu_text_ext (menu, 1, pos, text);
71  } /* set_menu_state */  }
72    
73    
74  /* Use the common dialog to request a file from the user.  /* Set the state of a menu item @m_uid to @state. */
75     id can be either FILE_OPEN or FILE_SAVE.  void
76     The return value is the file name or NULL if cancel was chosen. */  set_menu_state (HMENU menu, UINT m_uid, UINT state)
77  const char *  {      
78  get_filename_dlg (HWND hwnd, int id, const char * title,      MENUITEMINFO mii;
79                    const char * filter, const char * name)  
80  {      memset (&mii, 0, sizeof (mii));
81      static char file[512] = "";      mii.cbSize = sizeof (mii);
82      OPENFILENAME open;      mii.fMask = MIIM_STATE;
83            mii.fState = state;
84      if (name && strlen (name) < (sizeof (file)-1))      SetMenuItemInfo (menu, m_uid, FALSE, &mii);
85          strcpy (file, name);  }
86      else  
87          memset (file, 0, sizeof (file));  
88      if (!filter)  /* Retrieve the state of the menu item @m_uid and return it. */
89          filter = _("All Files (*.*)\0*.*\0\0");  UINT
90      memset (&open, 0, sizeof (open));  get_menu_state (HMENU menu, UINT m_uid)
91      open.lStructSize = sizeof (OPENFILENAME);  {
92      open.hInstance = glob_hinst;      MENUITEMINFO mii;
93      open.lpstrTitle = title;  
94      open.lpstrFilter = filter;      memset (&mii, 0, sizeof (mii));
95      open.hwndOwner = hwnd;      mii.cbSize = sizeof (mii);
96      open.lpstrFile = file;      mii.fMask = MIIM_STATE;
97      open.nMaxFile = sizeof (file) - 1;      GetMenuItemInfo (menu, m_uid, FALSE, &mii);
98      if (id == FILE_OPEN)      return mii.fState;
99          open.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;  }
100      else  
101          open.Flags = OFN_OVERWRITEPROMPT;  
102    enum {
103      if (id == FILE_OPEN && GetOpenFileName (&open))      CDLG_FILE_OPEN = 0,
104          return open.lpstrFile;      CDLG_FILE_SAVE = 1
105      else if (id == FILE_SAVE && GetSaveFileName (&open))  };
106          return open.lpstrFile;  
107        /* Use the common dialog to request a file from the user.
108      return NULL;     id can be either FILE_OPEN or FILE_SAVE.
109  }     The return value is the file name or NULL if cancel was chosen. */
110    const char *
111  /* Use the common dialog to allow the user to select a folder.  get_filename_dlg (HWND hwnd, int id, const char * title,
112     The return value is either the folder path or NULL if cancel was chosen. */                    const char * filter, const char * name)
113  const char*  {
114  get_folder_dlg (HWND hwnd, const char * title, const char * name)      static char file[512] = "";
115  {      OPENFILENAME open;
116      static char folder[MAX_PATH+1] = "";      
117      BROWSEINFO bi;      if (name && strlen (name) < (sizeof (file)-1))
118      ITEMIDLIST * il;          strcpy (file, name);
119        else
120      memset (&bi, 0, sizeof (bi));          memset (file, 0, sizeof (file));
121      bi.hwndOwner = hwnd;      if (!filter)
122      if (title)          filter = "All Files (*.*)\0*.*\0\0";
123          bi.lpszTitle = title;      /* XXX: problem with gettext because of the 'artificial'
124      if (name && strlen (name) < MAX_PATH-1)              double string termination!. */
125          strcpy (folder, name);      memset (&open, 0, sizeof (open));
126      else      open.lStructSize = sizeof (OPENFILENAME);
127          memset (folder, 0, sizeof (folder));      open.hInstance = glob_hinst;
128      il = SHBrowseForFolder (&bi);      open.lpstrTitle = title;
129      if (il) {      open.lpstrFilter = filter;
130          SHGetPathFromIDList (il, folder);      open.hwndOwner = hwnd;
131          _SHFree (il);      open.lpstrFile = file;
132          return folder;      open.nMaxFile = sizeof (file) - 1;
133      }      if (id == CDLG_FILE_OPEN)
134      return NULL;          open.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
135  }      else
136            open.Flags = OFN_OVERWRITEPROMPT;
137    
138  /* Return the clipboard contents as a string or NULL      if (id == CDLG_FILE_OPEN && GetOpenFileName (&open))
139     if the clipboard does not contain text. */          return open.lpstrFile;
140  char*      else if (id == CDLG_FILE_SAVE && GetSaveFileName (&open))
141  get_clip_text (HWND hwnd)          return open.lpstrFile;
142  {      
143      HANDLE clipmem;      return NULL;
144      char *cliptxt, *p;    }
145      int len;  
146        const char*
147      if (OpenClipboard (hwnd) == FALSE)  get_filesave_dlg (HWND hwnd, const char *title,
148          return NULL;                    const char *filter, const char *name)
149      clipmem = GetClipboardData (CF_TEXT);  {
150      if (clipmem == NULL) {      return get_filename_dlg (hwnd, CDLG_FILE_SAVE, title, filter, name);
151          p = NULL;  }
152          goto leave;  
153      }  const char*
154      cliptxt = (char *) GlobalLock (clipmem);  get_fileopen_dlg (HWND hwnd, const char *title, const char *filter,
155      if (cliptxt == NULL) {                    const char *name)
156          p = NULL;  {
157          goto leave;      return get_filename_dlg (hwnd, CDLG_FILE_OPEN, title, filter, name);
158      }  }
159        
160      len =  strlen (cliptxt);  
161      p = new char[len + 1];  /* Use the common dialog to allow the user to select a folder.
162      if (!p)     The return value is either the folder path or NULL if cancel was chosen. */
163          BUG (NULL);  const char*
164      memcpy (p, cliptxt, len);  get_folder_dlg (HWND hwnd, const char *title, const char *name)
165      p[len] = '\0';  {
166      GlobalUnlock (clipmem);      static char folder[MAX_PATH+1] = "";
167            BROWSEINFO bi;
168  leave:      ITEMIDLIST *il;
169      CloseClipboard ();  
170      return p;      memset (&bi, 0, sizeof (bi));
171  }      bi.hwndOwner = hwnd;
172        if (title)
173            bi.lpszTitle = title;
174  /* Set the the given text to the clipboard. */      if (name && strlen (name) < MAX_PATH-1)
175  int          strcpy (folder, name);
176  set_clip_text (HWND hwnd, const char *text, int nbytes)      else
177  {              memset (folder, 0, sizeof (folder));
178      HANDLE clipmem;      il = SHBrowseForFolder (&bi);
179      int rc = 0;      if (il) {
180      char *p;          SHGetPathFromIDList (il, folder);
181                _SHFree (il);
182      if (OpenClipboard (hwnd) == FALSE)            return folder;
183          return WPTERR_CLIP_OPEN;      }
184      EmptyClipboard ();      return NULL;
185    }
186      clipmem = GlobalAlloc (GHND, nbytes + 1);  
187      if (clipmem == NULL)  
188          BUG (NULL);  /* Return the clipboard contents as a string or NULL
189      p = (char *) GlobalLock (clipmem);     if the clipboard does not contain text. */
190      if (p == NULL) {  char*
191          rc = WPTERR_GENERAL;;  get_clip_text (HWND hwnd)
192          goto leave;      {
193      }      HANDLE clipmem;
194      memcpy (p, text, nbytes);      char *cliptxt, *p;  
195      p[nbytes] = '\0';      int len;
196            
197      GlobalUnlock (clipmem);      if (OpenClipboard (hwnd) == FALSE)
198      SetClipboardData (CF_TEXT, clipmem);          return NULL;
199            clipmem = GetClipboardData (CF_TEXT);
200  leave:      if (clipmem == NULL) {
201      CloseClipboard ();          p = NULL;
202      return rc;          goto leave;
203  } /* set_clip_text */      }
204        cliptxt = (char *) GlobalLock (clipmem);
205        if (cliptxt == NULL) {
206  /* Append or prepend some text to the clipboard contents.          p = NULL;
207     If as_footer = 1, append the text otherwise prepend. */          goto leave;
208  int      }
209  set_clip_text2 (HWND hwnd, const char *text, int nbytes, int as_footer)      
210  {      len =  strlen (cliptxt);
211      char *p, *new_text;      p = new char[len + 1];
212        if (!p)
213      p = get_clip_text (hwnd);          BUG (NULL);
214      if (!p)      memcpy (p, cliptxt, len);
215          return WPTERR_CLIP_GET;      p[len] = '\0';
216      new_text = new char [strlen (p)+strlen (text)+8];      GlobalUnlock (clipmem);
217      if (!new_text)      
218          BUG (0);  leave:
219      if (as_footer == 0)      CloseClipboard ();
220          sprintf (new_text, "%s\r\n%s\r\n\r\n", text, p);      return p;
221      else  }
222          sprintf (new_text, "%s\n%s\n\n", p, text);  
223      set_clip_text (hwnd, new_text, strlen (new_text)+1);  
224      free_if_alloc (p);  /* Set @text as the new clipboard content. */
225      free_if_alloc (new_text);  int
226      return 0;  set_clip_text (HWND hwnd, const char *text, int nbytes)
227  }  {    
228        HANDLE clipmem;
229        int rc = 0;
230  /* Make a file name out of the path, the file and an extension. */      char *p;
231  char*      
232  make_filename (const char *path, const char *file, const char *ext)      if (OpenClipboard (hwnd) == FALSE)  
233  {          return WPTERR_CLIP_OPEN;
234      char *p;      EmptyClipboard ();
235      size_t size = 0;  
236        clipmem = GlobalAlloc (GHND, nbytes + 1);
237      if( path && *path )      if (clipmem == NULL)
238          size += strlen( path );          BUG (NULL);
239      if( file && *file )      p = (char *) GlobalLock (clipmem);
240          size += strlen( file );      if (p == NULL) {
241      if( ext && *ext )          rc = WPTERR_GENERAL;;
242          size += strlen( ext );          goto leave;    
243      p = new char[size + 4];      }
244      memset( p, 0, size );      memcpy (p, text, nbytes);
245      if( path ) {      p[nbytes] = '\0';
246          strcat( p, path );      
247          if( path[strlen( path ) -1] != '\\' )      GlobalUnlock (clipmem);
248              strcat( p, "\\" );      SetClipboardData (CF_TEXT, clipmem);
249      }      
250      if( file )  leave:
251          strcat( p, file );      CloseClipboard ();
252      if( ext ) {      return rc;
253          strcat( p, "." );  } /* set_clip_text */
254          strcat( p, ext );  
255      }  
256      return p;  /* Append or prepend some text to the clipboard contents.
257  } /* make_filename */     If as_footer = 1, append the text otherwise prepend. */
258    int
259    set_clip_text2 (HWND hwnd, const char *text, int nbytes, int as_footer)
260  /* return 0 if it exists, otherwise >0. */  {
261  int      char *p, *new_text;
262  file_exist_check (const char * fname)  
263  {            p = get_clip_text (hwnd);
264      HANDLE fh;        if (!p)
265            return WPTERR_CLIP_GET;
266      fh = CreateFile( fname, GENERIC_READ, FILE_SHARE_READ,      new_text = new char [strlen (p)+strlen (text)+8];
267                       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );      if (!new_text)
268      if( fh == INVALID_HANDLE_VALUE )          BUG (0);
269          return WPTERR_FILE_EXIST;      if (as_footer == 0)
270      CloseHandle( fh );          sprintf (new_text, "%s\r\n%s\r\n\r\n", text, p);
271      return 0;      else
272  }          sprintf (new_text, "%s\n%s\n\n", p, text);
273        set_clip_text (hwnd, new_text, strlen (new_text)+1);
274        free_if_alloc (p);
275  /* Check if the current folder exists.      free_if_alloc (new_text);
276     Return 0 for success. */      return 0;
277  int  }
278  dir_exist_check (const char *dir)  
279  {  
280      struct stat statbuf;      /* Make a file name out of the path @path, the file @file and
281           an extension. @ext.
282      if( stat( dir, &statbuf ) == -1 )     Return value: the full file name on success. */
283          return WPTERR_GENERAL;  char*
284      if( statbuf.st_mode & _S_IFDIR )  make_filename (const char *path, const char *file, const char *ext)
285          return 0;  {
286      return WPTERR_GENERAL;      char *p;
287  }      size_t size = 0;
288    
289        if( path && *path )
290  /* Return the file size of the given file. */          size += strlen( path );
291  size_t      if( file && *file )
292  get_file_size (const char *fname)          size += strlen( file );
293  {      if( ext && *ext )
294      size_t fsize;          size += strlen( ext );
295      HANDLE fh;      p = new char[size + 4];
296        memset( p, 0, size );
297      fh = CreateFile( fname, GENERIC_READ, FILE_SHARE_READ,      if( path ) {
298                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );          strcat( p, path );
299      if( fh == INVALID_HANDLE_VALUE )          if( path[strlen( path ) -1] != '\\' )
300          return 0;              strcat( p, "\\" );
301      fsize = GetFileSize( fh, NULL );      }
302      if( fsize == 0xFFFFFFFF )      if( file )
303          fsize = 0;          strcat( p, file );
304      CloseHandle( fh );      if( ext ) {
305      return fsize;          strcat( p, "." );
306  } /* get_file_size */          strcat( p, ext );
307        }
308        return p;
309  int  }
310  init_file_lock( LOCK *ctx, const char *file )  
311  {  
312        /* Generate a file name from a special dirctory. */
313      ctx->size = get_file_size( file );  char*
314      ctx->file = m_strdup( file );  make_special_filename (int folder, const char *file, const char *ext)
315      ctx->fh = CreateFile( file, GENERIC_READ, FILE_SHARE_READ, NULL,  {
316                           OPEN_ALWAYS, 0, NULL );      BOOL ec;
317      if( ctx->fh == INVALID_HANDLE_VALUE )      char path[MAX_PATH], *p;
318          return WPTERR_GENERAL;      size_t n=0;
319      if( LockFile( ctx->fh, 0, 0, ctx->size, 0 ) == FALSE ) {  
320          CloseHandle( ctx->fh );      /* MSDN: buf must be at least MAX_PATH=256 bytes */
321          ctx->fh = INVALID_HANDLE_VALUE;      ec = SHGetSpecialFolderPath (HWND_DESKTOP, path, folder, TRUE);
322          ctx->size = 0;      if (ec != 1) {
323          free( ctx->file );          log_debug ("SHGetSpecialFolderPath() failed\r\n", (int)GetLastError ());
324          return WPTERR_GENERAL;          return NULL;
325      }      }
326      return 0;  
327  } /* init_file_lock */      n = strlen (path)+1;
328        if (file)
329            n += strlen (file)+1;
330  void      if (ext)
331  release_file_lock( LOCK *ctx )          n += strlen (ext)+1;
332  {      p = new char[n+2];
333      free_if_alloc( ctx->file );      if (!p)
334      ctx->file = NULL;          BUG (0);
335      ctx->size = 0;      memset (p, 0, n+2);
336      CloseHandle( ctx->fh );      strcpy (p, path);    
337  } /* release_file_lock */      if (file) {
338            strcat (p, "\\");
339            strcat (p, file);
340  /* Start a dialog with the exception that before it is checked that the      }
341     dialog is not already openened. */      if (ext)
342  int          strcat (p, ext);
343  dialog_box_param( HINSTANCE hinst, LPCTSTR name, HWND parent, DLGPROC fnc,      return p;
344                                    LPARAM param, LPCTSTR title, int title_id )  }
345  {  
346      #ifndef LANG_DE  
347      if( FindWindowEx( GetDesktopWindow(), NULL, NULL, title ) )  /* return 0 if the file @fname exists, otherwise >0. */
348          return -1;        int
349      #else  file_exist_check (const char *fname)
350      char strdesc[256];  {
351      LoadString( glob_hinst, title_id, strdesc, sizeof (strdesc) -1 );      struct stat st;
352      if( FindWindowEx( GetDesktopWindow(), NULL, NULL, strdesc ) )      if (stat (fname, &st) == -1)
353          return -1;          return WPTERR_FILE_EXIST;
354      #endif      return 0;
355        }
356      return DialogBoxParam( hinst, name, parent, fnc, param );  
357  } /* dialog_box_param */  
358    /* Check if the current folder exists.
359       Return 0 for success. */
360  /* Wrapper for message box which forces the message box into the  int
361     foreground and it is displayed always on top. */  dir_exist_check (const char *dir)
362  int  {
363  msg_box (HWND hwnd, const char *text, const char *title, int mode)      struct stat statbuf;    
364  {      
365      mode |= MB_SETFOREGROUND;      if (stat (dir, &statbuf) == -1)
366      mode |= MB_TASKMODAL;          return WPTERR_GENERAL;
367      mode |= MB_TOPMOST;      if (statbuf.st_mode & _S_IFDIR)
368      return MessageBox(hwnd, text, title, mode);          return 0;
369  }      return WPTERR_GENERAL;
370    }
371    
372  void  
373  set_active_window( HWND dlg)  /* Return the file size of the given file @fname. */
374  {        DWORD
375      activ_hwnd = dlg;  get_file_size (const char *fname)
376  } /* set_active_window */  {
377        DWORD fsize;
378  void      HANDLE fh;
379  reset_active_window( void )  
380  {            fh = CreateFile (fname, GENERIC_READ, FILE_SHARE_READ,
381      activ_hwnd = NULL;                       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
382  } /* reset_active_window */      if (fh == INVALID_HANDLE_VALUE)
383            return 0;
384        fsize = GetFileSize (fh, NULL);
385  static DWORD CALLBACK      if (fsize == 0xFFFFFFFF)
386  reminder_thread (void *ctx)          fsize = 0;
387  {      CloseHandle (fh);
388      reminder_ctx_s *c = (reminder_ctx_s *)ctx;      return fsize;
389    }
390      Sleep( c->msecs );  
391      SetForegroundWindow( activ_hwnd );  
392    /* Start a dialog with the exception that before it is checked that the
393      return 0;     dialog is not already openened. */
394  } /* reminder_thread */  int
395    dialog_box_param (HINSTANCE hinst, LPCTSTR name, HWND parent, DLGPROC fnc,
396                      LPARAM param, LPCTSTR title, int title_id)
397  HANDLE  {
398  window_reminder( struct reminder_ctx_s *ctx )      if (FindWindowEx (GetDesktopWindow (), NULL, NULL, title))
399  {          return -1;
400      DWORD tid = 0;      return DialogBoxParam (hinst, name, parent, fnc, param);
401        }
402      return CreateThread( NULL, 0, reminder_thread, ctx, 0, &tid );  
403  } /* window_reminder */  
404    /* Wrapper for message box which forces the message box into the
405       foreground and it is displayed always on top. */
406  char*  int
407  m_strdup (const char *str)  msg_box (HWND hwnd, const char *text, const char *title, int mode)
408  {  {
409      char * p = new char[strlen (str) + 1];      mode |= MB_SETFOREGROUND;
410      if (p)      mode |= MB_TASKMODAL;
411          strcpy (p, str);      mode |= MB_TOPMOST;
412      return p;      return MessageBox(hwnd, text, title, mode);
413  } /* m_strdup */  }
414    
415    
416  /* Center the hwndChild relative to parent.  /* Safe strdup version (C++ version). */
417     The style param allows to specificy additional styles (like topmost). */  char*
418  void  m_strdup (const char *str)
419  center_window2 (HWND hwndChild, HWND parent, HWND style)  {
420  {          char *p = new char[strlen (str) + 1];
421      HWND hwndParent;      if (!p)
422      RECT rChild, rParent;              BUG (NULL);
423      HDC hdc;      strcpy (p, str);
424      int wChild, hChild, wParent, hParent;          return p;
425      int wScreen, hScreen, xNew, yNew;  }
426      int flags = SWP_NOSIZE | SWP_NOZORDER;  
427    
428      hwndParent = parent;  /* Center the hwndChild relative to parent.
429      if (hwndParent == NULL)     The style param allows to specificy additional styles (like topmost). */
430          hwndParent = GetDesktopWindow ();  void
431      GetWindowRect (hwndChild, &rChild);      center_window2 (HWND hwndChild, HWND parent, HWND style)
432      wChild = rChild.right - rChild.left;      {    
433      hChild = rChild.bottom - rChild.top;      HWND hwndParent;
434        RECT rChild, rParent;    
435      GetWindowRect (hwndParent, &rParent);          HDC hdc;
436      wParent = rParent.right - rParent.left;          int wChild, hChild, wParent, hParent;    
437      hParent = rParent.bottom - rParent.top;            int wScreen, hScreen, xNew, yNew;
438            int flags = SWP_NOSIZE | SWP_NOZORDER;
439      hdc = GetDC (hwndChild);      
440      wScreen = GetDeviceCaps (hdc, HORZRES);          hwndParent = parent;
441      hScreen = GetDeviceCaps (hdc, VERTRES);          if (hwndParent == NULL)
442      ReleaseDC (hwndChild, hdc);                hwndParent = GetDesktopWindow ();
443      xNew = rParent.left + ((wParent - wChild) /2);          GetWindowRect (hwndChild, &rChild);    
444      if (xNew < 0)      wChild = rChild.right - rChild.left;    
445          xNew = 0;      hChild = rChild.bottom - rChild.top;
446      else if ((xNew+wChild) > wScreen)  
447          xNew = wScreen - wChild;      GetWindowRect (hwndParent, &rParent);    
448      yNew = rParent.top  + ((hParent - hChild) /2);      wParent = rParent.right - rParent.left;    
449      if (yNew < 0)      hParent = rParent.bottom - rParent.top;      
450          yNew = 0;      
451      else if ((yNew+hChild) > hScreen)      hdc = GetDC (hwndChild);    
452          yNew = hScreen - hChild;      wScreen = GetDeviceCaps (hdc, HORZRES);    
453      if (style == HWND_TOPMOST || style == HWND_NOTOPMOST)      hScreen = GetDeviceCaps (hdc, VERTRES);    
454          flags = SWP_NOMOVE | SWP_NOSIZE;      ReleaseDC (hwndChild, hdc);      
455      SetWindowPos (hwndChild, style? style : NULL, xNew, yNew, 0, 0, flags);      xNew = rParent.left + ((wParent - wChild) /2);    
456  }      if (xNew < 0)
457            xNew = 0;
458        else if ((xNew+wChild) > wScreen)
459  /* Center the given hwndChild window with no special style. */          xNew = wScreen - wChild;
460  void      yNew = rParent.top  + ((hParent - hChild) /2);
461  center_window (HWND hwndChild, HWND hwndParent)      if (yNew < 0)
462  {          yNew = 0;
463      center_window2 (hwndChild, hwndParent, NULL);      else if ((yNew+hChild) > hScreen)
464  }          yNew = hScreen - hChild;
465        if (style == HWND_TOPMOST || style == HWND_NOTOPMOST)
466            flags = SWP_NOMOVE | SWP_NOSIZE;
467        SetWindowPos (hwndChild, style? style : NULL, xNew, yNew, 0, 0, flags);
468    }
469    
470    
471    /* Center the given hwndChild window with no special style. */
472    void
473    center_window (HWND hwndChild, HWND hwndParent)
474    {
475        center_window2 (hwndChild, hwndParent, NULL);
476    }
477    
478    
479    /* Retrieve the product verion of the given file @fname.
480       Format: MAJOR.MINOR.PATCH1.PATCH2
481       Return value: 0 on success. */
482    int
483    get_file_version (const char *fname, WORD *major, WORD *minor,
484                      WORD *patch1, WORD *patch2)
485    {
486        VS_FIXEDFILEINFO *inf = {0};
487        char file[MAX_PATH+1] = {0};
488        LPVOID buf, data;
489        DWORD arg;
490        DWORD size;
491        UINT qlen;
492    
493        strncpy (file, fname, MAX_PATH);
494        size = GetFileVersionInfoSize (file, &arg);
495        if (!size)
496            return -1;
497        buf = (LPVOID)new CHAR[size];
498        if (!buf)
499            BUG (NULL);
500        GetFileVersionInfo (file, 0, size, buf);
501    
502        qlen=0;
503        VerQueryValue (buf, "\\", &data, &qlen);
504        if (!qlen) {
505            delete [] (char*)buf;
506            return -1;
507        }
508        inf = (VS_FIXEDFILEINFO*)data;
509    
510        if (major)
511            *major = HIWORD (inf->dwProductVersionMS);
512        if (minor)
513            *minor = LOWORD (inf->dwProductVersionMS);
514        if (patch1)
515            *patch1 = HIWORD (inf->dwProductVersionLS);    
516        if (patch2)
517            *patch2 = LOWORD (inf->dwProductVersionLS);
518    
519        delete [] (char*)buf;
520        return 0;
521    }
522    
523    
524    /* Return date in a format which complies with the
525       system locale settings. */
526    const char*
527    get_locale_date (long tm_t, char *buf, DWORD buflen)
528    {
529        SYSTEMTIME st;
530        struct tm *ptm;
531    
532        ptm = localtime (&tm_t);  
533        st.wYear = (WORD)ptm->tm_year;
534        st.wMonth = (WORD)ptm->tm_mon;
535        st.wDay = (WORD)ptm->tm_mday;
536        st.wYear += 1900;
537        st.wMonth += 1;
538        if (!GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,
539                            NULL, buf, buflen))
540            return NULL;
541        return buf;
542    }
543    
544    
545    struct reminder_hd_s {
546        int msecs;
547        HWND dlg;
548        HANDLE hd;
549    };
550    
551    
552    static DWORD CALLBACK
553    foreground_reminder_thread (void *c)
554    {
555        struct reminder_hd_s *ctx = (struct reminder_hd_s *)c;
556        Sleep (ctx->msecs);
557        SetForegroundWindow (ctx->dlg);
558        CloseHandle (ctx->hd);
559        delete ctx;
560        ExitThread (0);
561        return 0;
562    }
563    
564    /* Try to force the window @dlg to the foreground.
565       On NT5 or later this will not work if the user
566       is working in another window (console for example). */
567    void
568    force_foreground_window (HWND dlg, int msecs)
569    {
570        struct reminder_hd_s *hd;
571        DWORD tid;
572    
573        hd = new reminder_hd_s;
574        hd->dlg = dlg;
575        hd->msecs = msecs;
576        hd->hd = CreateThread (NULL, 0, foreground_reminder_thread,
577                               hd, NULL, &tid);
578    }

Legend:
Removed from v.23  
changed lines
  Added in v.167

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26