문제

저는 OpenGL용 이식성 레이어 작업 중입니다(Linux 및 Windows용 glX 및 wgl 항목 추상화).어쨌든 Window를 생성하는 방법이 있습니다.부모를 전달하지 않으면 프레임이 있는 실제 창이 나타납니다.부모를 전달하면 테두리도 없고 프레임도 없는 창이 나타납니다.

1개의 스레드에서 모든 작업을 수행하는 한 이것은 잘 작동합니다.다른 스레드가 하위 창을 만들려고 시도하자마자 win32 호출 "CreateWindow()"에서 앱 교착 상태가 발생합니다.어떤 아이디어가 있나요?

도움이 되었습니까?

해결책

이것은 실제 대답은 아니지만, 많은 사람들이 Win32가 부모보다 다른 실로 자녀를 창출하는 것을 금지한다고 믿는 것처럼 보이기 때문에, 나는 그 반대의 시위를 게시해야한다고 생각합니다.

아래 코드는 다른 사람에 속하는 부모의 자녀 창의 생성을 보여줍니다. 프로세스. 창 핸들 값을 명령 줄 매개 변수로 받아들이고 해당 부모의 자식 창을 만듭니다.

// t.cpp

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

#define CLASS_NAME L"fykshfksdafhafgsakr452"


static LRESULT CALLBACK WindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch ( msg )
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);
            EndPaint(hwnd, &ps);
            break;
        }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}



int main( int argc, char* argv[] )
{
    HWND parent = (argc >= 2) ? (HWND)strtoul(argv[1], 0, 0) : (HWND)0;
    printf("parent: 0x%x\n", parent);

    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_ACTIVECAPTION + 1);
    if ( !RegisterClass(&wc) )
    {
        printf("%d: error %d\n", __LINE__, GetLastError());
        return 0;
    }

    const DWORD style = WS_CHILD | WS_VISIBLE;

    HWND hwnd = CreateWindow(CLASS_NAME, L"Test", style, 50, 50, 100, 100,
                             parent, 0, wc.hInstance, 0);

    if ( !hwnd )
    {
        printf("%d: error %d\n", __LINE__, GetLastError());
        return 0;
    }

    MSG msg;
    while ( GetMessage(&msg, 0, 0, 0) )
        DispatchMessage(&msg);

    return 0;
}

다음 명령으로 이것을 컴파일합니다 (MSVC 명령 줄 환경 사용) :

cl /EHsc /DUNICODE /D_UNICODE t.cpp user32.lib

그런 다음 Spy ++ 또는 기타 도구를 사용하여 모든 창의 핸들 값 (예 : 메모장 또는이 사이트를보고있는 브라우저)을 얻습니다. 0x00001234라고 가정 해 봅시다. 그런 다음 컴파일 된 샘플을 사용하여 실행하십시오 t.exe 0x1234. Ctrl-C를 사용하여 T.exe를 종료하거나 콘솔 창을 닫습니다.

다른 팁

자식 창이 생성되면 SendMessage. 그러나 그 점에 유의하십시오 SendMessage 스레드 경계를 가로 질러 스레드와 달리 PostMessage. 부모 창의 실이 자식 실을 기다리고 있고 자식 스레드가 부모가 해당 스레드에있는 창을 만들려고한다면 교착 상태입니다.

일반적으로, 나는 실을 가로 질러 어린이 부모 관계를 만드는 것이 좋은 생각이라고 생각하지 않습니다. 교착 상태를 매우 쉽게 만들 수 있습니다.

여기에는 다른 스레드에 자녀와 부모의 창문을 갖지 않아야한다고 말하고 오히려 작동하지 않을 것이라고 강조한 답변이 여기에 있습니다.

그렇다면 Windows는 CreateWindow를 호출하려고 할 때 약간의 보호 조치를 취하고 단순히 실패합니다. 이제 주요 문제를 일으킬 수있는 스레드 커플 링 문제가 있지만, 이러한 제약 조건으로는 지원되는 시나리오입니다.

이것은 흥미로운 질문입니다.많은 구식 win32 사용자들이 나에게 이 작업을 수행할 수 없다고 말했습니다.이를 조사하면서 다음 포럼을 발견했습니다. 문자 보내().내 현재 이론은 CreateWindowEx()가 존재 권한을 요청하기 위해(또는 적어도 그 존재를 알리기 위해) 부모 창에 메시지(SendMessage()를 통해 차단)를 보내야 한다는 것입니다.어쨌든 상위 스레드가 이러한 메시지를 자유롭게 처리할 수 있는 한 모든 것이 작동합니다...

창은 스레드를 생성하는 스레드에 묶여 있습니다 (특히 스레드의 메시지 대기열에). 부모 창은 자식 창과 다른 스레드에 상주 할 수 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top