MINOR: Tweak About box and traymenu pos
[openwide.git] / owUtil.c
blobf85f7fcaffe802d551356d240aec2381c3dace6a
1 /*
2 * Openwide -- control Windows common dialog
3 *
4 * Copyright (c) 2000 Luke Hudson
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program 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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <windows.h>
24 /**
25 * @author Luke Hudson
26 * @licence GPL2
29 #include <objbase.h>
30 #include <shobjidl.h>
31 #include <shlguid.h>
32 #include <shlobj.h>
33 #include <shlwapi.h>
34 #include <shellapi.h>
35 #include <stdio.h>
36 #include "openwidedll.h"
37 #include "openwideres.h"
38 #include "owutil.h"
39 #include "owSharedUtil.h"
42 /* Attempt to convert from dialog units (measures used in .rc files) to pixels onscreen */
43 int dlgUnits2Pix(HWND hwnd, int units, BOOL bHorz)
45 RECT r;
46 SetRect(&r, 0,0,units,units);
47 MapDialogRect(hwnd, &r);
48 return (bHorz) ? r.right : r.bottom;
51 int pix2DlgUnits(HWND hwnd, int pix, BOOL bHorz)
53 RECT r;
54 SetRect(&r, 0,0,10,10);
55 MapDialogRect(hwnd, &r);
56 return (bHorz) ? (pix / r.right) : (pix / r.bottom);
59 /* Copied from Pro2
60 * Function source : C:\Code\lcc\Proto\util.c */
61 void Error(char *szError, ...)
63 char szBuff[256];
64 va_list vl;
65 va_start(vl, szError);
66 vsnprintf(szBuff, 256, szError, vl); // print error message to string
67 OutputDebugString(szBuff);
68 MessageBox(NULL, szBuff, "Error", MB_OK); // show message
69 va_end(vl);
70 exit(-1);
73 UINT APIENTRY OFNHookProcOldStyle(
74 HWND hdlg, // handle to the dialog box window
75 UINT uiMsg, // message identifier
76 WPARAM wParam, // message parameter
77 LPARAM lParam // message parameter
80 return FALSE;
86 char *Prompt_File_Name(int iFlags, HWND hwOwner, const char *pszFilter, const char *pszTitle)
88 static char szFileName[MAX_PATH]; // store selected file
89 char szDefFilter[] = "All Files\0*.*\0\0"; // default filter
90 OPENFILENAME ofn;
92 ZeroMemory(&ofn, sizeof(ofn));
93 ofn.lStructSize = sizeof(ofn);
95 szFileName[0] = 0; // mark the file name buffer as empty;
97 ofn.hwndOwner = hwOwner;
98 // If a filter is supplied, use it. Otherwise, use default.
99 ofn.lpstrFilter = (pszFilter) ? pszFilter : szDefFilter;
100 ofn.lpstrFile = szFileName; // where to store filename
101 ofn.nMaxFile = MAX_PATH; // length of filename buffer
102 ofn.lpstrTitle = pszTitle; // title if supplied
104 if(iFlags == 1)
106 ofn.Flags = OFN_EXPLORER // use new features
107 | OFN_CREATEPROMPT // create files if user wishes
108 | OFN_OVERWRITEPROMPT
109 | OFN_PATHMUSTEXIST // what it says
110 | OFN_HIDEREADONLY; // hide the read-only option
111 if(pszFilter)
113 int i;
114 for(i=0; pszFilter[i]!=0; i++)
116 i++;
117 char *sp= strchr(&pszFilter[i], '.');
118 if(sp) ofn.lpstrDefExt = sp+1;
120 if(!GetSaveFileName(&ofn))
121 return NULL;
122 return szFileName;
124 else
126 // ofn.lpfnHook = OFNHookProcOldStyle;
127 // ofn.Flags = OFN_ENABLEHOOK;
128 ofn.Flags = OFN_EXPLORER // use new features
129 | OFN_FILEMUSTEXIST // file names must be valid
130 | OFN_PATHMUSTEXIST // and paths too.
131 | OFN_HIDEREADONLY; // hide the read-only option
132 // dbg("Address of OFN data is %p, structsize is %lu", &ofn, ofn.lStructSize);
133 if(!GetOpenFileName(&ofn))
134 return NULL;
135 return szFileName;
137 /* MSG msg;
138 while (PeekMessage(&msg, hwOwner, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE));*/
144 TCHAR *lbGetItemText(HWND hwLB, int iItem)
146 TCHAR *szText = NULL;
147 int len;
148 len = SendMessage(hwLB, LB_GETTEXTLEN, iItem, 0) + 1;
149 if(len <= 1)
150 return NULL;
151 szText = malloc(len+1 * sizeof(char));
152 if(!szText) return NULL;
153 len = SendMessage(hwLB, LB_GETTEXT, iItem, (LPARAM)szText);
154 if( len <= 0 )
155 free(szText);
156 return szText;
160 static int AddRem_TrayIcon(HICON hIcon, char *szTip, HWND hwnd, UINT uMsg, DWORD dwState, DWORD dwMode){
162 NOTIFYICONDATA nid;
164 memset(&nid, 0, sizeof(NOTIFYICONDATA));
165 nid.cbSize = sizeof(NOTIFYICONDATA);
166 nid.hWnd = hwnd;
167 nid.uFlags = NIF_MESSAGE | (hIcon ? NIF_ICON : 0) | (szTip ? NIF_TIP : 0);
168 nid.hIcon = hIcon;
169 nid.uCallbackMessage = uMsg;
171 if( szTip )
173 strncpy(nid.szTip, szTip, 63);
174 nid.szTip[63] = 0;
177 //nid.dwState = dwState;
178 return (Shell_NotifyIcon(dwMode, &nid) != 0);
183 int Add_TrayIcon(HICON hIcon, char *szTip, HWND hwnd, UINT uMsg, DWORD dwState){
184 return AddRem_TrayIcon(hIcon, szTip, hwnd, uMsg, dwState, NIM_ADD);
188 void EndTrayOperation(void)
190 NOTIFYICONDATA nid = {0};
191 nid.cbSize = sizeof(NOTIFYICONDATA);
192 Shell_NotifyIcon(NIM_SETFOCUS, &nid);
196 int Rem_TrayIcon(HWND hwnd, UINT uMsg, DWORD dwState){
197 return AddRem_TrayIcon(NULL, NULL, hwnd, uMsg, dwState, NIM_DELETE);
201 BOOL delFile(HWND hwnd, const char *szFile)
203 SHFILEOPSTRUCT shlOp = {0};
204 shlOp.hwnd = hwnd;
205 shlOp.wFunc = FO_DELETE;
206 shlOp.pFrom = szFile;
207 shlOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS | FOF_NORECURSION;
208 return (SHFileOperation(&shlOp) == S_OK);
215 BOOL fileExists (const char *path)
217 int errCode;
219 if (GetFileAttributes (path) == 0xFFFFFFFF)
221 errCode = GetLastError ();
222 if (errCode == ERROR_FILE_NOT_FOUND
223 || errCode == ERROR_PATH_NOT_FOUND)
224 return FALSE;
225 //dbg ("fileExists? getLastError gives %d", errCode);
227 return TRUE;
230 // CreateLink - uses the Shell's IShellLink and IPersistFile interfaces
231 // to create and store a shortcut to the specified object.
233 // Returns the result of calling the member functions of the interfaces.
235 // Parameters:
236 // lpszPathObj - address of a buffer containing the path of the object.
237 // lpszPathLink - address of a buffer containing the path where the
238 // Shell link is to be stored.
239 // lpszDesc - address of a buffer containing the description of the
240 // Shell link.
242 HRESULT CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc)
244 HRESULT hres;
245 IShellLink* psl;
247 // Get a pointer to the IShellLink interface.
248 hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
249 &IID_IShellLink, (LPVOID*)&psl);
250 if (SUCCEEDED(hres))
252 IPersistFile* ppf;
254 // Set the path to the shortcut target and add the description.
255 psl->lpVtbl->SetPath(psl, lpszPathObj);
256 psl->lpVtbl->SetDescription(psl, lpszDesc);
258 // Query IShellLink for the IPersistFile interface for saving the
259 // shortcut in persistent storage.
260 hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
262 if (SUCCEEDED(hres))
264 WCHAR wsz[MAX_PATH];
266 // Ensure that the string is Unicode.
267 MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
269 // TODO: Check return value from MultiByteWideChar to ensure success.
270 // Save the link by calling IPersistFile::Save.
271 hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
272 ppf->lpVtbl->Release(ppf);
274 psl->lpVtbl->Release(psl);
276 return hres;
279 int cbAddString(HWND hwCB, const char *szStr, LPARAM lpData)
281 int idx = SendMessage(hwCB, CB_ADDSTRING, 0, (LPARAM)szStr);
282 if( idx != CB_ERR )
284 int res = SendMessage(hwCB, CB_SETITEMDATA, idx, lpData);
285 if( res == CB_ERR )
287 SendMessage(hwCB, CB_DELETESTRING, idx, 0);
288 idx = CB_ERR;
291 return idx;
294 int getDlgItemRect(HWND hwnd, UINT uID, LPRECT pr)
296 if(!IsWindow(hwnd) || !pr)
297 return 0;
298 HWND hwCtl = GetDlgItem(hwnd, uID);
299 if(!hwCtl)
300 return 0;
301 if(!GetWindowRect(hwCtl, pr))
302 return 0;
303 MapWindowPoints(NULL, hwnd, (LPPOINT)&pr->left, 2);
304 return 1;
309 BOOL waitForMutex(void)
311 DWORD dwRes;
312 if( !ghMutex )
314 ghMutex = OpenMutex(SYNCHRONIZE, FALSE, OW_MUTEX_NAME);
316 if( ghMutex )
318 dwRes = WaitForSingleObject(ghMutex, INFINITE);
319 switch(dwRes)
321 case WAIT_OBJECT_0:
322 // okay, continue
323 break;
324 case WAIT_ABANDONED:
325 default:
326 //dbg("Mutex wait failed");
327 return FALSE;
330 return TRUE;
333 void releaseMutex(void)
335 if( ghMutex )
337 ReleaseMutex(ghMutex);