📄 wakeupdemo2.cpp
字号:
// Windows Mobile Programming by Examples
// copuright (c) windowsmobilepro@yahoo.com
// http://windowsmobilepro.blogspot.com
#include <windows.h>
#include <windowsx.h>
#include "notify.h"
#include <aygshell.h>
#include "resource.h"
// a unique String as a mutex
TCHAR* g_szMutex = TEXT("WakeupDemo");
TCHAR* g_szEventName = TEXT("WakeupEvent");
HINSTANCE g_hInst = NULL;
HWND g_hwndChild = NULL; // Handle to the Edit Control
const TCHAR g_cszAppName[] = TEXT("WakeupDemo Application"); //Window Class
const TCHAR g_cszTitle[] = TEXT("WakeupDemo"); //Window Title
#define dim(x) (sizeof(x) / sizeof(x[0]))
#define ALERT(str) MessageBox(NULL, (str), NULL, MB_SETFOREGROUND|MB_TOPMOST)
static LPTSTR FormatCurrentTime(LPTSTR szCurrentTime)
{
const TCHAR *days[] = {L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat"};
const TCHAR *months[] = {L"", L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun",
L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec"};
SYSTEMTIME st;
memset(&st, 0, sizeof(SYSTEMTIME));
GetLocalTime(&st);
wsprintf(szCurrentTime, TEXT("%s, %02d %s %04d %02d:%02d:%02d"),
days[st.wDayOfWeek],
st.wDay,
months[st.wMonth],
st.wYear,
st.wHour,
st.wMinute,
st.wSecond);
return szCurrentTime;
}
static HRESULT AddWakeupNotification(LPCTSTR szEventName)
{
HRESULT hr = S_OK;
HANDLE hNotify = NULL;
CE_NOTIFICATION_TRIGGER notifTrigger;
memset(¬ifTrigger, 0, sizeof(CE_NOTIFICATION_TRIGGER));
notifTrigger.dwSize = sizeof(CE_NOTIFICATION_TRIGGER);
TCHAR szNamedEventExeName[MAX_PATH];
memset(szNamedEventExeName, 0, sizeof(TCHAR)*MAX_PATH);
_tcscat(szNamedEventExeName, NAMED_EVENT_PREFIX_TEXT);
_tcscat(szNamedEventExeName, szEventName);
notifTrigger.dwType = CNT_EVENT;
notifTrigger.dwEvent = NOTIFICATION_EVENT_WAKEUP;
notifTrigger.lpszApplication = szNamedEventExeName;
hNotify = CeSetUserNotificationEx(0, ¬ifTrigger, NULL);
// NULL because we do not care what action to take
if (!hNotify) {
// ... error handling
hr = E_FAIL;
} else {
CloseHandle(hNotify);
}
return hr;
}
static HRESULT ClearWakeupNotification(LPCTSTR szEventName)
{
HRESULT hr = S_OK;
TCHAR szToCompare[MAX_PATH];
memset(szToCompare, 0, sizeof(TCHAR)*MAX_PATH);
_tcscat(szToCompare, NAMED_EVENT_PREFIX_TEXT);
_tcscat(szToCompare, szEventName);
PBYTE pBuff = (PBYTE)LocalAlloc(LPTR, 8192);
if (!pBuff) {
return E_OUTOFMEMORY;
}
// at most 256 notification handles - should be more than enough for a typical device
HANDLE hNotifHandlers[256];
DWORD nNumHandlers, nNumClearedHandlers = 0;
DWORD i = 0;
int rc = CeGetUserNotificationHandles(hNotifHandlers, dim(hNotifHandlers), &nNumHandlers);
if (!rc) {
// ... error handling
hr = E_FAIL;
goto FuncExit;
}
for (; i<nNumHandlers; i++) {
// query info for this specific handler
BOOL bClearThis = FALSE;
DWORD dwSize = 0;
rc = CeGetUserNotification(hNotifHandlers[i], 8192, &dwSize, pBuff);
if (!rc) continue;
PCE_NOTIFICATION_INFO_HEADER pnih = (PCE_NOTIFICATION_INFO_HEADER)pBuff;
PCE_NOTIFICATION_TRIGGER pNotifTrigger = pnih->pcent;
// Notice some events with NULL lpszApplication might be inserted!
if (pNotifTrigger && pNotifTrigger->lpszApplication && !_tcsicmp(pNotifTrigger->lpszApplication, szToCompare)) {
bClearThis = TRUE;
}
if (bClearThis && CeClearUserNotification(pnih->hNotification)) {
nNumClearedHandlers++;
}
}
FuncExit:
if (pBuff) {
LocalFree(pBuff);
}
return hr;
}
static void OutputString(LPCTSTR lptszBuffer)
{
Edit_SetSel(g_hwndChild, Edit_GetTextLength(g_hwndChild), Edit_GetTextLength(g_hwndChild));
Edit_ReplaceSel(g_hwndChild, lptszBuffer);
}
typedef struct _EVENTHANDLES {
HANDLE hWakeupEvent;
HANDLE hThreadStop;
} EVENTHANDLES, *PEVENTHANDLES;
static DWORD WakeupEventListener(LPVOID lpData)
{
TCHAR szBuf[256];
PEVENTHANDLES pEventHandles = (PEVENTHANDLES)lpData;
while (TRUE) {
ResetEvent(pEventHandles->hWakeupEvent);
DWORD dwResult = WaitForMultipleObjects(2, (HANDLE*)pEventHandles, FALSE, INFINITE);
if (WAIT_OBJECT_0 == dwResult) {
_tcscpy(szBuf, TEXT("Wakeup at "));
FormatCurrentTime(szBuf+_tcslen(szBuf));
_tcscat(szBuf, TEXT("\r\n\r\n"));
OutputString(szBuf);
} else if (WAIT_OBJECT_0+1 == dwResult) {
break;
} else {
// WAIT_ABANDONED and WAIT_FAILED
// Abondoned is not possible, failed most probably means the Handle is closed
if (WAIT_FAILED == dwResult) {
// ... do something error processing
}
}
}
return S_OK;
}
static HRESULT StartWakeupEventListener(const PEVENTHANDLES pEventHandles, HANDLE& hThread)
{
DWORD dwDummy = 0;
hThread = CreateThread(NULL, 0, WakeupEventListener, (LPVOID)pEventHandles, 0, &dwDummy);
// need to error handling if thread creation failed
return S_OK;
}
static HRESULT StopWakeupEventListener(const PEVENTHANDLES pEventHandles, HANDLE& hThread)
{
DWORD dwMilliSec = 2000;
if (hThread) {
PulseEvent(pEventHandles->hThreadStop);
DWORD dwResult = WaitForSingleObject(hThread, dwMilliSec);
if (WAIT_OBJECT_0 != dwResult) {
// error or timeout. terminate the thread anyway
TerminateThread(hThread, -1);
}
CloseHandle(hThread);
hThread = NULL;
}
return S_OK;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT Msg, WPARAM wp, LPARAM lp)
{
LRESULT lResult = TRUE;
switch(Msg)
{
case WM_CREATE:
{
RECT rect;
SHMENUBARINFO mbi;
//Create a MenuBar
ZeroMemory(&mbi, sizeof(mbi));
mbi.cbSize = sizeof(mbi);
mbi.hwndParent = hwnd;
mbi.nToolBarId = IDM_MAIN_MENU;
mbi.hInstRes = g_hInst;
if(TRUE == SHCreateMenuBar(&mbi))
{
GetClientRect(hwnd, &rect);
//Create an edit box the size of the parent window
g_hwndChild = CreateWindow(TEXT("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE,
rect.left, rect.top, rect.right, rect.bottom,
hwnd, (HMENU)ID_CHILD, g_hInst, NULL);
if(NULL != g_hwndChild)
{
ShowWindow(g_hwndChild, SW_SHOW);
UpdateWindow(g_hwndChild);
//Now show the information
break;
}
}
MessageBox(hwnd,
TEXT("CreateWindow Failed"),
TEXT("Error"),
MB_OK | MB_ICONERROR);
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
break;
case WM_COMMAND:
switch(GET_WM_COMMAND_ID(wp, lp))
{
case IDM_VIEW_TEST:
SetFocus(g_hwndChild);
break;
case IDM_MAIN_MENUITEM2:
DestroyWindow(hwnd);
break;
default:
lResult = DefWindowProc(hwnd, Msg, wp, lp);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_ACTIVATE:
if(wp)
{
SetFocus(g_hwndChild);
}
//Drop through
default:
lResult = DefWindowProc(hwnd, Msg, wp, lp);
break;
}
return lResult;
}
// InitInstance
BOOL InitInstance(HINSTANCE hInstance, int CmdShow)
{
g_hInst = hInstance;
HWND hWndMain = CreateWindow(
g_cszAppName, g_cszTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
if(NULL == hWndMain) {
return FALSE;
}
ShowWindow(hWndMain, CmdShow);
UpdateWindow(hWndMain);
return TRUE;
}
// InitApplication
BOOL InitApplication(HINSTANCE hInstance)
{
WNDCLASS wc;
InitCommonControls();
wc.style = CS_HREDRAW | CS_VREDRAW ;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIcon = NULL;
wc.hInstance = hInstance;
wc.hCursor = NULL; // No cursor if target is not NT
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_cszAppName;
return RegisterClass(&wc);
}
// WinMain
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int CmdShow
)
{
//Check to see if app is running then pop to foreground
HWND hWndPrevious = FindWindow(g_cszAppName, g_cszTitle);
if (NULL != hWndPrevious) {
SetForegroundWindow((HWND)(((ULONG)hWndPrevious) | 0x01));
return 0;
}
if (!InitApplication(hInstance)) {
return FALSE;
}
if(!InitInstance(hInstance, CmdShow)) {
return FALSE;
}
// create an wakeup named event
HRESULT hr = ClearWakeupNotification(g_szEventName);
hr = AddWakeupNotification(g_szEventName);
HANDLE hWakeupEvent = CreateEvent(NULL, TRUE, FALSE, g_szEventName);
HANDLE hThreadStopEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("ThreadStop"));
EVENTHANDLES eventHandles = {hWakeupEvent, hThreadStopEvent};
HANDLE hWakeupEventListenerThread = NULL;
hr = StartWakeupEventListener(&eventHandles, hWakeupEventListenerThread);
TCHAR szBuf[256];
while (TRUE) {
MSG currentMsg;
int nGetMsg = GetMessage(¤tMsg, NULL, 0, 0);
if (nGetMsg > 0) {
TranslateMessage(¤tMsg);
DispatchMessage(¤tMsg);
swprintf(szBuf, TEXT("GetMsg %d, %d, %d\r\n"), currentMsg.message, currentMsg.wParam, currentMsg.lParam);
FormatCurrentTime(szBuf+_tcslen(szBuf));
_tcscat(szBuf, TEXT("\r\n\r\n"));
OutputString(szBuf);
} else if (nGetMsg < 0) {
OutputString(TEXT("GetMsg failed"));
} else {
break;
}
}
hr = StopWakeupEventListener(&eventHandles, hWakeupEventListenerThread);
// thread handle already closed
hr = ClearWakeupNotification(g_szEventName);
CloseHandle(hWakeupEvent);
CloseHandle(hThreadStopEvent);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -