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
13 #define ok_hr(status, expected) ok_hex(status, expected)
15 #define HRESULT_CANCELLED HRESULT_FROM_WIN32(ERROR_CANCELLED)
18 /* An implementation of the IQueryContinue interface */
19 class CQueryContinue
: public IQueryContinue
25 CQueryContinue(HRESULT hContinue
= S_OK
) : m_hContinue(hContinue
) {}
28 CQueryContinue
& operator=(const CQueryContinue
& qc
)
31 m_hContinue
= qc
.m_hContinue
;
35 CQueryContinue
& operator=(HRESULT hContinue
)
37 m_hContinue
= hContinue
;
48 virtual ULONG STDMETHODCALLTYPE
AddRef()
53 virtual ULONG STDMETHODCALLTYPE
Release()
58 virtual HRESULT STDMETHODCALLTYPE
QueryInterface(REFIID riid
, void **ppvObject
)
64 virtual HRESULT STDMETHODCALLTYPE
QueryContinue(void)
66 // TRACE("IQueryContinue::QueryContinue() returning 0x%lx\n", m_hContinue);
73 TestNotification(void)
76 CComPtr
<IUserNotification
> pUserNotif
;
77 CQueryContinue
queryContinue(S_OK
);
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
);
86 skip("Could not instantiate IUserNotification\n");
90 /* Set an invalid icon for the notification icon */
91 hr
= pUserNotif
->SetIconInfo((HICON
)0xdeadbeef, L
"Tooltip text");
95 /* Seting an invalid string would crash the application */
96 hr
= pUserNotif
->SetIconInfo(NULL
, (LPCWSTR
)0xdeadbeef);
100 /* Set a default icon for the notification icon */
101 hr
= pUserNotif
->SetIconInfo(NULL
, L
"Tooltip text");
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.
110 /* Set up a balloon associated to the notification icon */
111 hr
= pUserNotif
->SetBalloonInfo(L
"Balloon title", L
"Balloon text", NIIF_ERROR
);
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...
118 hr
= pUserNotif
->SetBalloonRetry(2000, 1000, 2);
121 /* Display the balloon and also the tooltip if one points on the icon */
122 hr
= pUserNotif
->Show(NULL
, 0);
123 ok_hr(hr
, HRESULT_CANCELLED
);
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().
131 hr
= pUserNotif
->SetIconInfo(NULL
, NULL
);
134 /* Display the balloon and also the tooltip if one points on the icon */
135 hr
= pUserNotif
->Show(NULL
, 0);
136 ok_hr(hr
, HRESULT_CANCELLED
);
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.
142 hr
= pUserNotif
->SetBalloonInfo(NULL
, L
"Balloon text", NIIF_WARNING
);
145 hr
= pUserNotif
->Show(NULL
, 0);
146 ok_hr(hr
, HRESULT_CANCELLED
);
149 /* Test support of the IQueryContinue interface */
151 hr
= pUserNotif
->SetBalloonInfo(L
"Balloon title", L
"Balloon text", NIIF_WARNING
);
154 hr
= pUserNotif
->Show(&queryContinue
, 2000); /* Timeout of 2 seconds */
155 ok_hr(hr
, HRESULT_CANCELLED
);
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
);
162 hr
= pUserNotif
->Show(&queryContinue
, 2000); /* Timeout of 2 seconds */
163 ok_hr(hr
, HRESULT_CANCELLED
);
166 hr
= pUserNotif
->SetBalloonInfo(L
"Balloon title", L
"Balloon text", NIIF_WARNING
);
169 queryContinue
= S_FALSE
;
170 hr
= pUserNotif
->Show(&queryContinue
, 2000); /* Timeout of 2 seconds */
176 TestThread(LPVOID lpParam
)
179 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
184 /* Cleanup and return */
189 START_TEST(CUserNotification
)
194 /* We create a test thread, because the notification tests can hang */
195 hThread
= CreateThread(NULL
, 0, TestThread
, NULL
, 0, NULL
);
196 ok(hThread
!= NULL
, "CreateThread failed with error 0x%lu\n", GetLastError());
199 skip("Could not create the CUserNotification test thread!");
203 /* Wait a maximum of 1:30 for the thread to finish (the timeout tests take some time) */
204 dwWait
= WaitForSingleObject(hThread
, 90 * 1000);
205 ok(dwWait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lu, expected WAIT_OBJECT_0\n", dwWait
);
207 /* Cleanup and return */
208 CloseHandle(hThread
);