ReactOS 0.4.16-dev-109-gf4cb10f
CUserNotification.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Test for CUserNotification
5 * COPYRIGHT: Copyright 2018 Hermes Belusca-Maito
6 */
7
8#include "shelltest.h"
9
10#define NDEBUG
11#include <debug.h>
12
13#define ok_hr(status, expected) ok_hex(status, expected)
14
15#define HRESULT_CANCELLED HRESULT_FROM_WIN32(ERROR_CANCELLED)
16
17
18/* An implementation of the IQueryContinue interface */
19class CQueryContinue : public IQueryContinue
20{
21private:
23
24public:
25 CQueryContinue(HRESULT hContinue = S_OK) : m_hContinue(hContinue) {}
27
29 {
30 if (this != &qc)
32 return *this;
33 }
34
36 {
37 m_hContinue = hContinue;
38 return *this;
39 }
40
41 operator HRESULT()
42 {
43 return m_hContinue;
44 }
45
46public:
47 // IUnknown
49 {
50 return 1;
51 }
52
54 {
55 return 0;
56 }
57
59 {
60 return S_OK;
61 }
62
63 // IQueryContinue
65 {
66 // TRACE("IQueryContinue::QueryContinue() returning 0x%lx\n", m_hContinue);
67 return m_hContinue;
68 }
69};
70
71
72static void
74{
75 HRESULT hr;
76 CComPtr<IUserNotification> pUserNotif;
77 CQueryContinue queryContinue(S_OK);
78
79 // hr = pUserNotif.CoCreateInstance(CLSID_UserNotification);
80 hr = ::CoCreateInstance(CLSID_UserNotification, NULL, CLSCTX_ALL,
81 /*IID_PPV_ARG(IUserNotification, &pUserNotif)*/
82 IID_IUserNotification, (void**)&pUserNotif);
83 ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
84 if (FAILED(hr))
85 {
86 skip("Could not instantiate IUserNotification\n");
87 return;
88 }
89
90 /* Set an invalid icon for the notification icon */
91 hr = pUserNotif->SetIconInfo((HICON)UlongToHandle(0xdeadbeef), L"Tooltip text");
92 ok_hr(hr, S_OK);
93
94#if 0
95 /* Seting an invalid string would crash the application */
96 hr = pUserNotif->SetIconInfo(NULL, (LPCWSTR)0xdeadbeef);
97 ok_hr(hr, S_OK);
98#endif
99
100 /* Set a default icon for the notification icon */
101 hr = pUserNotif->SetIconInfo(NULL, L"Tooltip text");
102 ok_hr(hr, S_OK);
103
104 /*
105 * Since just displaying a notification icon without balloon hangs (expected),
106 * for making this test automatable we instead just test balloon functionality
107 * where timeouts can be programmed.
108 */
109
110 /* Set up a balloon associated to the notification icon */
111 hr = pUserNotif->SetBalloonInfo(L"Balloon title", L"Balloon text", NIIF_ERROR);
112 ok_hr(hr, S_OK);
113
114 /*
115 * Try to display twice the balloon if the user cancels it.
116 * Without setting balloon retry, we would wait for a very long time...
117 */
118 hr = pUserNotif->SetBalloonRetry(2000, 1000, 2);
119 ok_hr(hr, S_OK);
120
121 /* Display the balloon and also the tooltip if one points on the icon */
122 hr = pUserNotif->Show(NULL, 0);
124
125 /*
126 * Setting icon information *after* having enabled balloon info,
127 * allows to automatically set the notification icon according
128 * to the dwInfoFlags passed to SetBalloonInfo() and by giving
129 * NULL to the hIcon parameter of SetIconInfo().
130 */
131 hr = pUserNotif->SetIconInfo(NULL, NULL);
132 ok_hr(hr, S_OK);
133
134 /* Display the balloon and also the tooltip if one points on the icon */
135 hr = pUserNotif->Show(NULL, 0);
137
138 /*
139 * This line shows the balloon, but without title nor icon in it.
140 * Note that the balloon icon is not displayed when not setting any title.
141 */
142 hr = pUserNotif->SetBalloonInfo(NULL, L"Balloon text", NIIF_WARNING);
143 ok_hr(hr, S_OK);
144
145 hr = pUserNotif->Show(NULL, 0);
147
148
149 /* Test support of the IQueryContinue interface */
150
151 hr = pUserNotif->SetBalloonInfo(L"Balloon title", L"Balloon text", NIIF_WARNING);
152 ok_hr(hr, S_OK);
153
154 hr = pUserNotif->Show(&queryContinue, 2000); /* Timeout of 2 seconds */
156
157#if 0 // Commented because this test (the Show() call) is unreliable.
158 /* Try to hide the balloon by setting an empty string (can use either NULL or L"") */
159 hr = pUserNotif->SetBalloonInfo(L"Balloon title", NULL, NIIF_WARNING);
160 ok_hr(hr, S_OK);
161
162 hr = pUserNotif->Show(&queryContinue, 2000); /* Timeout of 2 seconds */
164#endif
165
166 hr = pUserNotif->SetBalloonInfo(L"Balloon title", L"Balloon text", NIIF_WARNING);
167 ok_hr(hr, S_OK);
168
169 queryContinue = S_FALSE;
170 hr = pUserNotif->Show(&queryContinue, 2000); /* Timeout of 2 seconds */
171 ok_hr(hr, S_FALSE);
172}
173
174DWORD
177{
178 /* Initialize COM */
180
181 /* Start the test */
183
184 /* Cleanup and return */
186 return 0;
187}
188
190{
192 DWORD dwWait;
193
194 /* We create a test thread, because the notification tests can hang */
196 ok(hThread != NULL, "CreateThread failed with error 0x%lu\n", GetLastError());
197 if (!hThread)
198 {
199 skip("Could not create the CUserNotification test thread!\n");
200 return;
201 }
202
203 /* Wait a maximum of 60 seconds for the thread to finish (the timeout tests take some time) */
204 dwWait = WaitForSingleObject(hThread, 60 * 1000);
205 ok(dwWait == WAIT_OBJECT_0, "WaitForSingleObject returned %lu, expected WAIT_OBJECT_0\n", dwWait);
206
207 /* Cleanup and return */
209}
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
virtual ULONG STDMETHODCALLTYPE Release()
CQueryContinue(HRESULT hContinue=S_OK)
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
CQueryContinue & operator=(HRESULT hContinue)
virtual HRESULT STDMETHODCALLTYPE QueryContinue(void)
CQueryContinue & operator=(const CQueryContinue &qc)
virtual ULONG STDMETHODCALLTYPE AddRef()
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
#define CALLBACK
Definition: compat.h:35
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
unsigned long DWORD
Definition: ntddk_ex.h:95
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
DWORD CALLBACK TestThread(LPVOID lpParam)
static void TestNotification(void)
#define HRESULT_CANCELLED
#define ok_hr(status, expected)
static HICON
Definition: imagelist.c:80
HANDLE hThread
Definition: wizard.c:28
#define L(x)
Definition: ntvdm.h:50
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t ULONG
Definition: typedefs.h:59
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WAIT_OBJECT_0
Definition: winbase.h:406
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define HRESULT
Definition: msvc.h:7
#define S_FALSE
Definition: winerror.h:2357
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185