source: trunk/testapp/gui/systray/StealthDialog.cpp@ 21999

Last change on this file since 21999 was 21999, checked in by dmik, 13 years ago

kernel32: Make SEH work in OS/2 context.

See #82 for details.

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1// Slightly modified to build out of the original package available at
2// http://www.codeproject.com/KB/shell/StealthDialog.aspx
3
4// Win32 Dialog.cpp : Defines the entry point for the application.
5//
6
7#include "stdafx.h"
8#include "resource.h"
9
10#define TRAYICONID 1// ID number for the Notify Icon
11#define SWM_TRAYMSG WM_APP// the message ID sent to our window
12
13#define SWM_SHOW WM_APP + 1// show the window
14#define SWM_HIDE WM_APP + 2// hide the window
15#define SWM_EXIT WM_APP + 3// close the window
16
17#ifndef _MSC_VER
18
19#include <odinlx.h>
20
21int APIENTRY _tWinMain(HINSTANCE hInstance,
22 HINSTANCE hPrevInstance,
23 LPTSTR lpCmdLine,
24 int nCmdShow);
25
26//Win32 resource table (produced by wrc)
27extern DWORD Resource_PEResTab;
28
29int main(int argc, char **argv)
30{
31#ifdef ODIN_FORCE_WIN32_TIB
32 ForceWin32TIB();
33#endif
34 RegisterLxExe((WINMAIN)_tWinMain, (PVOID)&Resource_PEResTab);
35}
36
37#endif
38
39// Global Variables:
40HINSTANCE hInst; // current instance
41NOTIFYICONDATA niData; // notify icon data
42
43// Forward declarations of functions included in this code module:
44BOOL InitInstance(HINSTANCE, int);
45BOOL OnInitDialog(HWND hWnd);
46void ShowContextMenu(HWND hWnd);
47ULONGLONG GetDllVersion(LPCTSTR lpszDllName);
48
49INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
50LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
51
52int APIENTRY _tWinMain(HINSTANCE hInstance,
53 HINSTANCE hPrevInstance,
54 LPTSTR lpCmdLine,
55 int nCmdShow)
56{
57 MSG msg;
58 HACCEL hAccelTable;
59
60 // Perform application initialization:
61 if (!InitInstance (hInstance, nCmdShow)) return FALSE;
62 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_STEALTHDIALOG);
63
64 // Main message loop:
65 while (GetMessage(&msg, NULL, 0, 0))
66 {
67 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)||
68 !IsDialogMessage(msg.hwnd,&msg) )
69 {
70 TranslateMessage(&msg);
71 DispatchMessage(&msg);
72 }
73 }
74 return (int) msg.wParam;
75}
76
77// Add tray icon
78VOID AddTrayIcon(HWND hWnd)
79{
80 // Fill the NOTIFYICONDATA structure and call Shell_NotifyIcon
81
82 // zero the structure - note: Some Windows funtions require this but
83 // I can't be bothered which ones do and
84 // which ones don't.
85 ZeroMemory(&niData,sizeof(NOTIFYICONDATA));
86
87#ifndef __WIN32OS2__
88 // get Shell32 version number and set the size of the structure
89 // note: the MSDN documentation about this is a little
90 // dubious and I'm not at all sure if the method
91 // bellow is correct
92 ULONGLONG ullVersion = GetDllVersion(_T("Shell32.dll"));
93 if(ullVersion >= MAKEDLLVERULL(5, 0,0,0))
94 niData.cbSize = sizeof(NOTIFYICONDATA);
95 else niData.cbSize = NOTIFYICONDATA_V2_SIZE;
96#else
97 niData.cbSize = sizeof(NOTIFYICONDATA);
98#endif
99
100 // the ID number can be anything you choose
101 niData.uID = TRAYICONID;
102
103 // state which structure members are valid
104 niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
105
106 // @todo: Note that there are two Odin-related bugs in this testcase
107 // presently:
108 //
109 // 1. Requesting an icon of the small size (e.g. 16x16) in LoadImage
110 // corrupts the result. Using LR_DEFAULTSIZE or requesting the
111 // normal size works.
112 // 2. StealthDialog.ico itself is strange. Both PMVIEW and Odin
113 // display some garbage lines in the background (probably, a
114 // transparency issue). The very same icon is shown on Win32 fine.
115 // Changing it to some other icon (e.g. tree.ico from src/shell32/ico)
116 // fixes the problem.
117 //
118 // Both problems need to be addressed one day.
119
120 // load the icon
121 niData.hIcon = (HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_STEALTHDLG),
122 IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),
123 LR_DEFAULTCOLOR);
124
125 // the window to send messages to and the message to send
126 // note: the message value should be in the
127 // range of WM_APP through 0xBFFF
128 niData.hWnd = hWnd;
129 niData.uCallbackMessage = SWM_TRAYMSG;
130
131 // tooltip message
132 lstrcpyn(niData.szTip, _T("Time flies like an arrow but\n fruit flies like a banana!"), sizeof(niData.szTip)/sizeof(TCHAR));
133
134 Shell_NotifyIcon(NIM_ADD,&niData);
135
136 // free icon handle
137 if(niData.hIcon && DestroyIcon(niData.hIcon))
138 niData.hIcon = NULL;
139}
140
141// Initialize the window
142BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
143{
144 // prepare for XP style controls
145 InitCommonControls();
146
147 // store instance handle and create dialog
148 hInst = hInstance;
149 HWND hWnd = CreateDialog( hInstance, MAKEINTRESOURCE(IDD_DLG_DIALOG),
150 NULL, (DLGPROC)DlgProc );
151 if (!hWnd) return FALSE;
152
153 AddTrayIcon(hWnd);
154
155 // call ShowWindow here to make the dialog initially visible
156
157 return TRUE;
158}
159
160BOOL OnInitDialog(HWND hWnd)
161{
162 HMENU hMenu = GetSystemMenu(hWnd,FALSE);
163 if (hMenu)
164 {
165 AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
166 AppendMenu(hMenu, MF_STRING, IDM_ABOUT, _T("About"));
167 }
168 HICON hIcon = (HICON)LoadImage(hInst,
169 MAKEINTRESOURCE(IDI_STEALTHDLG),
170 IMAGE_ICON, 0,0, LR_SHARED|LR_DEFAULTSIZE);
171 SendMessage(hWnd,WM_SETICON,ICON_BIG,(LPARAM)hIcon);
172 SendMessage(hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hIcon);
173 return TRUE;
174}
175
176// Name says it all
177void ShowContextMenu(HWND hWnd)
178{
179 POINT pt;
180 GetCursorPos(&pt);
181 HMENU hMenu = CreatePopupMenu();
182 if(hMenu)
183 {
184 if( IsWindowVisible(hWnd) )
185 InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION, SWM_HIDE, _T("Hide"));
186 else
187 InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION, SWM_SHOW, _T("Show"));
188 InsertMenu(hMenu, (UINT)-1, MF_BYPOSITION, SWM_EXIT, _T("Exit"));
189
190 // note: must set window to the foreground or the
191 // menu won't disappear when it should
192 SetForegroundWindow(hWnd);
193
194 TrackPopupMenu(hMenu, TPM_BOTTOMALIGN,
195 pt.x, pt.y, 0, hWnd, NULL );
196 DestroyMenu(hMenu);
197 }
198}
199
200#ifndef __WIN32OS2__
201// Get dll version number
202ULONGLONG GetDllVersion(LPCTSTR lpszDllName)
203{
204 ULONGLONG ullVersion = 0;
205 HINSTANCE hinstDll;
206 hinstDll = LoadLibrary(lpszDllName);
207 if(hinstDll)
208 {
209 DLLGETVERSIONPROC pDllGetVersion;
210 pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
211 if(pDllGetVersion)
212 {
213 DLLVERSIONINFO dvi;
214 HRESULT hr;
215 ZeroMemory(&dvi, sizeof(dvi));
216 dvi.cbSize = sizeof(dvi);
217 hr = (*pDllGetVersion)(&dvi);
218 if(SUCCEEDED(hr))
219 ullVersion = MAKEDLLVERULL(dvi.dwMajorVersion, dvi.dwMinorVersion,0,0);
220 }
221 FreeLibrary(hinstDll);
222 }
223 return ullVersion;
224}
225#endif
226
227// Message handler for the app
228INT_PTR CALLBACK DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
229{
230 static UINT wmTaskbarCreated;
231
232 int wmId, wmEvent;
233
234 switch (message)
235 {
236 case SWM_TRAYMSG:
237 switch(lParam)
238 {
239 case WM_LBUTTONDBLCLK:
240 ShowWindow(hWnd, SW_RESTORE);
241 break;
242 case WM_RBUTTONDOWN:
243 case WM_CONTEXTMENU:
244 ShowContextMenu(hWnd);
245 }
246 break;
247 case WM_SYSCOMMAND:
248 if((wParam & 0xFFF0) == SC_MINIMIZE)
249 {
250 ShowWindow(hWnd, SW_HIDE);
251 return 1;
252 }
253 else if(wParam == IDM_ABOUT)
254 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
255 break;
256 case WM_COMMAND:
257 wmId = LOWORD(wParam);
258 wmEvent = HIWORD(wParam);
259
260 switch (wmId)
261 {
262 case SWM_SHOW:
263 ShowWindow(hWnd, SW_RESTORE);
264 break;
265 case SWM_HIDE:
266 case IDOK:
267 ShowWindow(hWnd, SW_HIDE);
268 break;
269 case SWM_EXIT:
270 DestroyWindow(hWnd);
271 break;
272 case IDM_ABOUT:
273 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
274 break;
275 }
276 return 1;
277 case WM_INITDIALOG:
278 wmTaskbarCreated = RegisterWindowMessage(TEXT("TaskbarCreated"));
279 return OnInitDialog(hWnd);
280 case WM_CLOSE:
281 DestroyWindow(hWnd);
282 break;
283 case WM_DESTROY:
284 niData.uFlags = 0;
285 Shell_NotifyIcon(NIM_DELETE,&niData);
286 PostQuitMessage(0);
287 break;
288 default:
289 if (message == wmTaskbarCreated)
290 AddTrayIcon(hWnd);
291 break;
292 }
293 return 0;
294}
295
296// Message handler for about box.
297LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
298{
299 switch (message)
300 {
301 case WM_INITDIALOG:
302 return TRUE;
303
304 case WM_COMMAND:
305 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
306 {
307 EndDialog(hDlg, LOWORD(wParam));
308 return TRUE;
309 }
310 break;
311 }
312 return FALSE;
313}
Note: See TracBrowser for help on using the repository browser.