任何人都可以提供如何使用Windows ShutdownBlockReasonCreate的示例

-5 c++ winapi visual-c++

谁能提供一个简单明了的例子ShutdownBlockReasonCreate?我一直试图通过MSDN页面弄清楚它,但我不理解它,而且我已经厌倦了每次尝试测试它时都不能关闭我的电脑而且它不起作用.如果有人熟悉并且可以提供一个非常棒的简洁示例!

这是我到目前为止,但我做'

#include <Windows.h>
#include <iostream>
std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

int main(int argc, char* argv[])
{
    if (ShutdownBlockReasonCreate(GetForegroundWindow(), s2ws("TEST").c_str()) != 0)
        std::cout << "Success" << std::endl;
    else
        std::cout << "Failure" << std::endl;

    while (1) 
    {
        Sleep(1000);
        std::cout << "Testing..." << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ret*_*nja 7

这在Windows 7中适用于我.如果您愿意,也可以在控制台程序中执行此操作,这是一个更简单的编写示例.你应该添加错误检查,我没有保持简短.

#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

HINSTANCE hInst;
HWND hWnd;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    switch(message)
    {
        case WM_QUERYENDSESSION:
            return FALSE;
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;
        case WM_CREATE:
            ShutdownBlockReasonCreate(hWnd, L"Don't do it!");
            break;
        case WM_DESTROY:
            ShutdownBlockReasonDestroy(hWnd);
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TestClass";
    wcex.hIconSm = NULL;
    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    hInst = hInstance;
    RECT sz = {0, 0, 512, 512};
    AdjustWindowRect(&sz, WS_OVERLAPPEDWINDOW, TRUE);
    hWnd = CreateWindow(L"TestClass", L"Test Window", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, sz.right - sz.left, sz.bottom - sz.top,
        NULL, NULL, hInstance, NULL);
    if(!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return TRUE;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    MyRegisterClass(hInstance);
    if(!InitInstance(hInstance, nCmdShow))
    {
        return FALSE;
    }

    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
Run Code Online (Sandbox Code Playgroud)

控制台版本不需要完全不同,虽然您确实需要创建一个窗口并运行消息泵,所以我不确定它是通过GUI应用程序购买的.显然,如果你想在任何一个版本中工作,你很可能最终需要一个单独的窗口或你的工作线程.

这是我提出的最简单的控制台程序示例.您会注意到,除了ConsoleCtrlHandler之外,它几乎完全相同,可以截取关闭控制台窗口和杀死GUI窗口的各种方法.由于我不想在我的测试控制台项目中更改它,因此它也有望成为MBCS项目.

#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

HINSTANCE hInst;
HWND hWnd;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    switch(message)
    {
        case WM_QUERYENDSESSION:
            return FALSE;
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;
        case WM_CREATE:
            ShutdownBlockReasonCreate(hWnd, L"Don't do it!");
            break;
        case WM_DESTROY:
            ShutdownBlockReasonDestroy(hWnd);
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = "TestClass";
    wcex.hIconSm = NULL;
    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    hInst = hInstance;
    RECT sz = {0, 0, 512, 512};
    AdjustWindowRect(&sz, WS_OVERLAPPEDWINDOW, TRUE);
    hWnd = CreateWindow("TestClass", "Test Window", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, sz.right - sz.left, sz.bottom - sz.top,
        NULL, NULL, hInstance, NULL);
    if(!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return TRUE;
}

BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{
    if(dwCtrlType == CTRL_C_EVENT ||
        dwCtrlType == CTRL_BREAK_EVENT ||
        dwCtrlType == CTRL_CLOSE_EVENT)
    {
        SendMessage(hWnd, WM_CLOSE, 0, 0);
        return TRUE;
    }
    return FALSE;
}

int main()
{
    SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);

    HINSTANCE hInstance = GetModuleHandle(NULL);

    MyRegisterClass(hInstance);
    if(!InitInstance(hInstance, SW_HIDE))
    {
        return FALSE;
    }

    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
Run Code Online (Sandbox Code Playgroud)