您的位置:首页 > 其它

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

2012-09-03 10:49 120 查看












--------------------------------------------------------------------------------------------------------------------------------------- .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/原創。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: