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

Last change on this file since 21916 was 21603, checked in by dmik, 15 years ago

testapp/systray: Added "TaskbarCreated" support.

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