zoukankan      html  css  js  c++  java
  • 【原創】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/原創。

  • 相关阅读:
    Sexy Beach PR 汉化补丁+入门教程
    [Unity3D]Script 脚本全部编译器属性具体解释
    图论--最小生成树和最短路1
    软件设计师之路总结~引——时间的温度
    BZOJ1441: Min
    BZOJ1602: [Usaco2008 Oct]牧场行走
    BZOJ1600: [Usaco2008 Oct]建造栅栏
    BZOJ1599: [Usaco2008 Oct]笨重的石子
    BZOJ1601: [Usaco2008 Oct]灌水
    BZOJ1058: [ZJOI2007]报表统计
  • 原文地址:https://www.cnblogs.com/ZzzZzz/p/2668409.html
Copyright © 2011-2022 走看看