【原創】WinMo仿wp7關機、重啟、關屏(關機需HTCUtil支持)






--------------------------------------------------------------------------------------------------------------------------------------- .h
#include "RdWrtIni.h"
#include <time.h>
#include <atlbase.h>
#include <pm.h>
// 重啟數據定義
#define CTL_CODE( DeviceType, Function, Method, Access ) ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )
#define FILE_DEVICE_HAL 0x00000101
#define METHOD_BUFFERED 0
#define FILE_ANY_ACCESS 0
#define IOCTL_HAL_REBOOT CTL_CODE(FILE_DEVICE_HAL, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
extern "C" __declspec(dllimport) BOOL KernelIoControl(DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned);
#define MAX_LOADSTRING 100
#define TimeInterval 1 // 計時器間隔
#define PROFILE _T(".\\MetroOff.ini")
void DrawUI(HDC hDC, int type, int Distance); // 繪圖操作
void FillSolidRect(HDC hDC, RECT rect, COLORREF clr); // 填充純色(當Profile.isLoadImage == FALSE)
void CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime); // 用作釋放光標后滑塊恢復原狀
void ShutDownWM(); // 僅支持HTC
struct Profile
{
BOOL isLoadImage; // 是否加載圖片
WCHAR szScreenOff[MAX_PATH]; // 關屏圖片路徑
WCHAR szReboot[MAX_PATH]; // 重啟圖片路徑
WCHAR szShutDown[MAX_PATH]; // 關機圖片路徑
COLORREF clrScreenOff; // 關屏色彩
COLORREF clrReboot; // 重啟色彩
COLORREF clrShutDown; // 關機色彩
int Status; // 初始操作狀態:(0:關屏 1:關機 2:重啟)
};
Profile g_Profile; // 配置文件
int g_Pos; // 滑塊位置 注意:考慮最大最小值,防止超過最大位移
int g_Width; // 屏幕寬度
int g_Height; // 屏幕長度
POINT g_Spt; // 起始座標
POINT g_Ept; // 瞬時座標
UINT_PTR g_TimerID; // 定時器ID
HWND g_hWnd; // 全局窗口句柄
HFONT g_FontL; // 大字體 退出時銷毀
HFONT g_FontS; // 小字體 退出時銷毀
LOGFONT g_lf; // 初始化時使用
HDC g_ScrDC; // 原始桌面DC 退出時銷毀
HDC g_BkgDC; // 保存桌面的DC 退出時銷毀
HBITMAP g_BkgBmp; // 保存桌面的畫布 退出時銷毀
HBITMAP g_BlkBmp; // 內存畫布,用作滑塊貼圖 退出時銷毀
BOOL g_Drag; // 是否在拖動滑塊
--------------------------------------------------------------------------------------------------------------------------------------- .cpp
// MetroOff.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "MetroOff.h"
// 全局变量:
HINSTANCE g_hInst; // 当前实例
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE, LPTSTR);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
// 执行应用程序初始化:
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, _T("MetroOff.ico"));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
TCHAR szTitle[MAX_LOADSTRING] = _T(""); // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING] = _T("MetroOff"); // 主窗口类名
g_hInst = hInstance; // 将实例句柄存储在全局变量中
// 在应用程序初始化期间,应调用一次 SHInitExtraControls 以初始化
// 所有设备特定控件,例如,CAPEDIT 和 SIPPREF。
SHInitExtraControls();
//如果它已经在运行,则将焦点置于窗口上,然后退出
hWnd = FindWindow(szWindowClass, szTitle);
if (hWnd)
{
// 将焦点置于最前面的子窗口
// “| 0x00000001”用于将所有附属窗口置于前台并
// 激活这些窗口。
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
return 0;
}
if (!MyRegisterClass(hInstance, szWindowClass))
{
return FALSE;
}
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, SW_HIDE);
UpdateWindow(hWnd);
// 加入初始化代碼
g_Profile.isLoadImage = (BOOL)GetPrivateProfileInt(_T("Load"), _T("Bool"), 0, PROFILE);
GetPrivateProfileString(_T("Image"), _T("ScreenOff"), _T(""), g_Profile.szScreenOff, MAX_PATH, PROFILE);
GetPrivateProfileString(_T("Image"), _T("Reboot"), _T(""), g_Profile.szReboot, MAX_PATH, PROFILE);
GetPrivateProfileString(_T("Image"), _T("ShutDown"), _T(""), g_Profile.szShutDown, MAX_PATH, PROFILE);
g_Profile.clrScreenOff = (COLORREF)GetPrivateProfileInt(_T("Color"), _T("ScreenOff"), 47746, PROFILE);
g_Profile.clrReboot = (COLORREF)GetPrivateProfileInt(_T("Color"), _T("Reboot"), 14851176, PROFILE);
g_Profile.clrShutDown = (COLORREF)GetPrivateProfileInt(_T("Color"), _T("ShutDown"), 13260, PROFILE);
g_Profile.Status = (int)GetPrivateProfileInt(_T("Initial"), _T("Status"), 0, PROFILE);
g_Width = GetSystemMetrics(SM_CXSCREEN);
g_Height = GetSystemMetrics(SM_CYSCREEN);
g_Pos = g_Height / 2;
g_Spt.x = 0;
g_Spt.y = 0;
g_Ept.x = 0;
g_Ept.y = 0;
g_TimerID = 0;
g_hWnd = hWnd;
g_Drag = FALSE;
// 設置字體
memset(&g_lf, 0, sizeof(LOGFONT));
g_lf.lfQuality = CLEARTYPE_QUALITY;
g_lf.lfHeight = g_Width/5;
g_lf.lfWeight = g_Width/10;
g_FontL = CreateFontIndirect(&g_lf);
g_lf.lfHeight = g_Width/16;
g_lf.lfWeight = g_Width/16;
g_FontS = CreateFontIndirect(&g_lf);
// 獲取屏幕圖像
g_ScrDC = GetDC(NULL);
g_BkgBmp = CreateCompatibleBitmap(g_ScrDC, g_Width, g_Height);
g_BkgDC = CreateCompatibleDC(g_ScrDC);
SelectObject(g_BkgDC, g_BkgBmp);
BitBlt(g_BkgDC, 0, 0, g_Width, g_Height, g_ScrDC, 0, 0, SRCCOPY);
if (g_Profile.isLoadImage)
{
switch (g_Profile.Status)
{
case 0:
g_BlkBmp = SHLoadImageFile(W2T(g_Profile.szScreenOff));
break;
case 1:
g_BlkBmp = SHLoadImageFile(W2T(g_Profile.szShutDown));
break;
case 2:
g_BlkBmp = SHLoadImageFile(W2T(g_Profile.szReboot));
break;
default:
break;
}
}
else
{
g_BlkBmp = CreateCompatibleBitmap(g_ScrDC, g_Width, g_Height);
}
// 窗口全屏化
ShowWindow(hWnd, SW_SHOW);
RECT rc;
GetWindowRect(hWnd, &rc);
SHFullScreen(hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
HWND hWndCB = ::SHFindMenuBar(hWnd);
ShowWindow(hWndCB, SW_HIDE);
MoveWindow(hWnd,
rc.left,
rc.top - g_Width / 240 * 26,
rc.right,
rc.bottom + g_Width / 240 * 26,
TRUE);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
static SHACTIVATEINFO s_sai;
switch (message)
{
case WM_CREATE:
// 初始化外壳程序激活信息结构
memset(&s_sai, 0, sizeof (s_sai));
s_sai.cbSize = sizeof (s_sai);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
DrawUI(hdc, g_Profile.Status, g_Pos);
EndPaint(hWnd, &ps);
break;
case WM_ERASEBKGND:
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_QUIT:
ReleaseDC(NULL, g_ScrDC);
DeleteDC(g_BkgDC);
DeleteObject(g_BkgBmp);
if (g_Profile.isLoadImage)
{
DeleteObject(g_BlkBmp);
}
DeleteObject(g_FontL);
DeleteObject(g_FontS);
break;
case WM_ACTIVATE:
// 向外壳程序通知我们的激活消息
SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
break;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
break;
case WM_LBUTTONDOWN:
if (HIWORD(lParam) < g_Pos)
{
g_Drag = TRUE;
if (g_Spt.x == 0)
{
g_Spt.x = LOWORD(lParam);
g_Spt.y = HIWORD(lParam);
}
}
if (g_TimerID != 0)
{
KillTimer(NULL, g_TimerID);
g_TimerID = 0;
}
break;
case WM_MOUSEMOVE:
if (g_Drag)
{
g_Ept.x = LOWORD(lParam);
g_Ept.y = HIWORD(lParam);
g_Pos = g_Ept.y - g_Spt.y + g_Height/2;
if (g_Pos > g_Height)
{
g_Pos = g_Height;
}
else if (g_Pos < 0)
{
g_Pos = 0;
}
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
break;
case WM_LBUTTONUP:
if (g_Drag)
{
g_Ept.x = LOWORD(lParam);
g_Ept.y = HIWORD(lParam);
g_Pos = g_Ept.y - g_Spt.y + g_Height/2;
if (g_Pos > g_Height)
{
g_Pos = g_Height;
}
else if (g_Pos < 0)
{
g_Pos = 0;
}
POINT Dist;
Dist.x = g_Ept.x - g_Spt.x;
Dist.y = g_Ept.y - g_Spt.y;
if (Dist.x < 0)
{
Dist.x = -Dist.x;
}
if (Dist.y < 0)
{
Dist.y = -Dist.y;
}
if (Dist.x < 16 && Dist.y < 16)
{
g_Profile.Status += 1;
if (g_Profile.Status > 2)
{
g_Profile.Status = 0;
}
DeleteObject(g_BlkBmp);
switch (g_Profile.Status)
{
case 0:
g_BlkBmp = SHLoadImageFile(W2T(g_Profile.szScreenOff));
break;
case 1:
g_BlkBmp = SHLoadImageFile(W2T(g_Profile.szShutDown));
break;
case 2:
g_BlkBmp = SHLoadImageFile(W2T(g_Profile.szReboot));
break;
default:
break;
}
}
g_TimerID = SetTimer(NULL, 0, TimeInterval, TimerProc);
g_Drag = FALSE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void ShutDownWM()
{
typedef int(*lpAPIFun)(BOOL);
lpAPIFun HTCUtilDeviceOff;
HINSTANCE hDll = LoadLibrary(_T("HTCUtil.dll"));
if (hDll != NULL)
{
HTCUtilDeviceOff = (lpAPIFun)GetProcAddress(hDll, _T("HTCUtilDeviceOff"));
if (HTCUtilDeviceOff != NULL)
{
HTCUtilDeviceOff(TRUE);
}
else
{
PostQuitMessage(0);
}
}
else
{
PostQuitMessage(0);
}
FreeLibrary(hDll);
}
void FillSolidRect(HDC hDC, RECT rect, COLORREF clr)
{
SetBkColor(hDC, clr);
ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
}
void DrawUI(HDC hDC, int type, int Distance)
{
// 創建內存畫布,並將屏幕背景貼到內存畫布上
HDC MemDC = CreateCompatibleDC(NULL);
HBITMAP MemBmp = CreateCompatibleBitmap(g_ScrDC, g_Width, g_Height);
SelectObject(MemDC, MemBmp);
BitBlt(MemDC, 0, 0 , g_Width, g_Height, g_BkgDC, 0 , 0, SRCCOPY);
// 滑塊貼圖相關操作
HDC blkDC = CreateCompatibleDC(NULL); // 創建滑塊內存DC
SelectObject(blkDC, g_BlkBmp);
TCHAR strInfo[] = _T("向下滑动以关机"); // 初始化說明文字
RECT rc;
rc.left = 0;
rc.right = g_Width;
rc.top = 0;
rc.bottom = g_Height;
switch (type)
{
case 0: // 關屏
if (!g_Profile.isLoadImage)
{
FillSolidRect(blkDC, rc, g_Profile.clrScreenOff);
}
wsprintf(strInfo, _T("向下滑动以关屏"));
break;
case 1: // 關機
if (!g_Profile.isLoadImage)
{
FillSolidRect(blkDC, rc, g_Profile.clrShutDown);
}
wsprintf(strInfo, _T("向下滑动以关机"));
break;
case 2: // 重啟
if (!g_Profile.isLoadImage)
{
FillSolidRect(blkDC, rc, g_Profile.clrReboot);
}
wsprintf(strInfo, _T("向下滑动以重启"));
break;
default:
break;
}
BitBlt(MemDC, 0, 0, g_Width, Distance, blkDC, 0, g_Height - Distance, SRCCOPY);
// ------------------------------------------文字部份
SetBkMode(MemDC, TRANSPARENT);
SetTextColor(MemDC, RGB(255, 255, 255));
SelectObject(MemDC, g_FontL);
rc.left = g_Width/3;
rc.top = Distance - g_Height/2;
rc.bottom = Distance - g_Height/4;
// 時間貼圖
TCHAR str[8];
LPSYSTEMTIME lpSystemTime = new SYSTEMTIME;
GetLocalTime(lpSystemTime);
wsprintf(str, _T("%02d:%02d"), lpSystemTime->wHour, lpSystemTime->wMinute);
DrawText(MemDC, str, -1, &rc, DT_CENTER | DT_VCENTER);
// 文字貼圖
rc.left = 0;
rc.top = Distance - g_Height/16;
rc.bottom = Distance;
SelectObject(MemDC, g_FontS);
DrawText(MemDC, strInfo, -1, &rc, DT_CENTER | DT_VCENTER);
// 完成貼圖
BitBlt(hDC, 0, 0, g_Width, g_Height, MemDC, 0, 0, SRCCOPY);
// 清理
DeleteDC(MemDC);
DeleteDC(blkDC);
DeleteObject(MemBmp);
if (Distance >= g_Height)
{
switch (type)
{
case 0: // 關屏
ReleaseDC(NULL, g_ScrDC);
DeleteDC(g_BkgDC);
DeleteObject(g_BkgBmp);
if (g_Profile.isLoadImage)
{
DeleteObject(g_BlkBmp);
}
DeleteObject(g_FontL);
DeleteObject(g_FontS);
SetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);
exit(0);
break;
case 1: // 關機
ShutDownWM();
break;
case 2: // 重啟
KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL);
break;
default:
break;
}
}
else if (Distance <= g_Height/4)
{
PostQuitMessage(0);
}
}
void CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
if (g_Pos == g_Height/2)
{
InvalidateRect(g_hWnd, NULL, FALSE);
UpdateWindow(g_hWnd);
g_Spt.x = 0;
KillTimer(NULL, g_TimerID);
}
else
{
g_Pos = ((g_Pos - g_Height/2)*7)/8 + g_Height/2;
InvalidateRect(g_hWnd, NULL, FALSE);
UpdateWindow(g_hWnd);
}
}
由於用到了HTCUtil,因此關機只能用於HTC機型,其他機型只能實現休眠。
轉載請注明http://www.cnblogs.com/ZzzZzz/原創。

浙公网安备 33010602011771号