Windows 扩展样式错误?

问题描述 投票:0回答:1

我正在尝试为我的程序设置快捷键,以便:

Win + left
将窗口放在屏幕的左半部分(1/2),

然后

Win + up
将其放在屏幕的左上角(1/4)。

只有

WS_EX_STATICEDGE
(扩展样式之一)可以实现。

其他的要么需要按两次

Win left
才能变成1/2,要么只按一次
Win left
就变成1/4。

但是我遇到了一些很奇怪的情况:

hwnd = CreateWindowEx(WS_EX_STATICEDGE, "WindowClass", "Caption", WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, /* x */
                        CW_USEDEFAULT, /* y */
                        640,             /* width */
                        480,             /* height */
                        NULL, NULL, hInstance, NULL);

fprintf(stderr, "EX_STYLE: %#lX  ,  STYLE: %#lX\n", GetWindowLong(hwnd, GWL_EXSTYLE), GetWindowLong(hwnd, GWL_STYLE));
if (SetWindowLongPtrW(hwnd, GWL_EXSTYLE, WS_EX_WINDOWEDGE | WS_EX_STATICEDGE) == 0)
    ErrorExit((LPTSTR)L"SetWindowLongptrW()");
fprintf(stderr, "EX_STYLE: %#lX  ,  STYLE: %#lX\n", GetWindowLong(hwnd, GWL_EXSTYLE), GetWindowLong(hwnd, GWL_STYLE));

输出为:

EX_STYLE: 0X20100  ,  STYLE: 0X14CF0000
EX_STYLE: 0X20000  ,  STYLE: 0X14CF0000

WS_EX_STATICEDGE
0x20000
WS_EX_WINDOWEDGE
0x100
,来自 MSDN。

第一个输出应为

0x20000
,而第二个输出应为
0x20100
。为什么不行?

我试过

RegisterHotKey()
,不能像
Win up
那样注册热键,因为它已经注册了。

所有源代码如下,用于测试。使用mingw-gcc编译(

gcc main.c -mconsole
)。

此外,

SetWindowPos()
ShowWindow()
SetWindowLongPtr()
无法纠正。

#include <windows.h>
#include <stdio.h>
#include <strsafe.h>

void ErrorExit(LPTSTR lpszFunction)
{
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf,
        0, NULL);

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
                                      (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
    StringCchPrintf((LPTSTR)lpDisplayBuf,
                    LocalSize(lpDisplayBuf) / sizeof(TCHAR),
                    TEXT("%s failed with error %d: %s"),
                    lpszFunction, dw, lpMsgBuf);
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw);
}

/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {

    /* Upon destruction, tell the main thread to stop */
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        break;
    }

    /* All other messages (a lot of them) are processed using default procedures */
    default:
        return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}

/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wc; /* A properties struct of our window */
    HWND hwnd;     /* A 'HANDLE', hence the H, or a pointer to our window */
    MSG msg;       /* A temporary location for all messages */

    /* zero out the struct and set the stuff we want to modify */
    memset(&wc, 0, sizeof(wc));
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    /* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = "WindowClass";
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);   /* Load a standard icon */
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

hwnd = CreateWindowEx(WS_EX_STATICEDGE, "WindowClass", "Caption", WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, /* x */
                        CW_USEDEFAULT, /* y */
                        640,             /* width */
                        480,             /* height */
                        NULL, NULL, hInstance, NULL);

fprintf(stderr, "EX_STYLE: %#lX  ,  STYLE: %#lX\n", GetWindowLong(hwnd, GWL_EXSTYLE), GetWindowLong(hwnd, GWL_STYLE));
if (SetWindowLongPtrW(hwnd, GWL_EXSTYLE, WS_EX_WINDOWEDGE | WS_EX_STATICEDGE) == 0)
    ErrorExit((LPTSTR)L"SetWindowLongptrW()");
fprintf(stderr, "EX_STYLE: %#lX  ,  STYLE: %#lX\n", GetWindowLong(hwnd, GWL_EXSTYLE), GetWindowLong(hwnd, GWL_STYLE));

    if (hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    /*
        This is the heart of our program where all input is processed and
        sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
        this loop will not produce unreasonably high CPU usage
    */
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {                           /* If no error is received... */
        TranslateMessage(&msg); /* Translate key codes to chars if present */
        DispatchMessage(&msg);  /* Send it to WndProc */
    }
    return msg.wParam;
}

c++ c windows winapi
1个回答
0
投票

只有在

WS_EX_STATICEDGE|WS_EX_WINDOWEDGE
时才能成功将扩展样式设置为
CreateWindow()

稍后通过

SetWindowLong()
设置将会导致系统自动删除
WS_EX_WINDOWEDGE

来自“设置 WS_EX_WINDOWEDGE 实际上有什么作用吗?

Windows 95/98/Me 自动添加和删除 WS_EX_WINDOWEDGE 样式 适用于所有应用程序中的窗口。对于版本 3.x 应用程序,Windows 95/98/Me 将 WS_EX_WINDOWEDGE 样式添加到窗口,如果在版本 3.1 中, 窗口将有一个对话框边框或一个相当大的边框。 Windows 95/98/Me 如果窗口的样式发生更改,则删除 WS_EX_WINDOWEDGE 样式,以便 在 3.1 版本中将不再有对话框边框或相当大的边框。 Windows 95/98/Me 使用类似的标准来添加和删除 4.0 版或更高版本应用程序的 WS_EX_WINDOWEDGE 样式,除了 任何具有标题栏的窗口都会收到 WS_EX_WINDOWEDGE 样式, 无论窗口的其他边框样式如何。

© www.soinside.com 2019 - 2024. All rights reserved.