문제

함수가 있습니다 :

HWND createMainWindow(P2p_Socket_Machine * toSend){

    HWND hMainWnd = CreateWindow( 
        L"Class",/*(LPCWSTR) nameOfConference.c_str()*/L"Chat",  WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, 
    CW_USEDEFAULT, 0, 600,400, 
    (HWND)NULL, (HMENU)NULL, 
    /*(HINSTANCE)hlnstance*/NULL, NULL 
    ); 

    if (!hMainWnd) { 
        MessageBox(NULL, L"Cannot create main window", L"Error", MB_OK); 
        return 0; 
    }

    CreateWindowA("LISTBOX",NULL, WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|LBS_NOTIFY|LBS_MULTIPLESEL,310,30,255,275,hMainWnd,(HMENU)List_Box,NULL,NULL);

    CreateWindowExA(NULL,"BUTTON", "Refresh", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,385,310,100,24,hMainWnd,(HMENU)Button_Refresh, NULL ,NULL);

    CreateWindowExA(NULL,"BUTTON", "Send", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,385,334,100,24,hMainWnd,(HMENU)Button_Send, NULL ,NULL);

    CreateWindowExA(NULL,"BUTTON", "New", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,385,354,100,24,hMainWnd,(HMENU)Button_New, NULL ,NULL);

    CreateWindowA("EDIT",0,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_LEFT|ES_MULTILINE|WS_VSCROLL|WS_DISABLED,
    10,30,265,275,hMainWnd,(HMENU)Text_Box_Get,NULL,NULL);

    CreateWindowA("EDIT",0,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_LEFT|ES_MULTILINE|WS_VSCROLL,
    10,320,265,45,hMainWnd,(HMENU)Text_Box_Send,NULL,NULL);

    SetWindowLongPtr(hMainWnd,GWLP_USERDATA,(LONG_PTR)toSend);

    ShowWindow(hMainWnd, SW_SHOW); 
    //UpdateWindow(hMainWnd);

    return hMainWnd;

}
.

및 이것은 내 프로그램의 주요 부분입니다 :

int WINAPI WinMain(HINSTANCE hlnstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int 
nCmdShow) 
{
WNDCLASSEX wc; 
    wc.cbSize = sizeof(wc); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = MyFunc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = hlnstance; 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL; 
    wc.lpszClassName = L"Class"; 
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
HWND toSend = createMainWindow(P2pSocket);

//some code

hThread = CreateThread(NULL, 0, ClientThread, 
            Message2, 0, &dwThreadId);

        if (hThread == NULL)
        {
            cout<<"Create thread filed";
            exit(10);
        }


    while (GetMessage(&msg, NULL, 0, 0)) { 

        TranslateMessage(&msg); 
        DispatchMessage(&msg);

    }

    return msg.wParam;   
.

내 프로그램의 주요 부분에서 CreateMainWindow () 함수를 호출 할 때 그것은 그것이 해야하는 것처럼 작동하지만, 나는 그것을 실행할 때 내 스레드 (ClientThread)가 작동하지 않습니다. 메인 스레드에서만 Windows 만 만들어야한다는 것을 읽었습니다. 사실입니까? 그리고 그것이 사실이라면,이 함수를 메인 스레드에서 수행하기 위해 다른 Thead 에서이 함수를 호출하는 가장 간단한 방법은 무엇입니까?


감사합니다. 이제 문제를 알고 있지만 해결책으로 갇혀 있습니다. 내 클라이언트 스레드 코드는 다음과 같습니다.

while(1){

    vector<HWND> AllHandlers;

    pair<string,string> Answer = Pointer->receiveMsgByUdp();

    if(!Pointer->isMyLocalAddress(Answer.first)){

        int type = messageUdpContentType(Answer.second);

        switch(type){

        case 0 :

            Pointer->sendMsgToIpUdp(Answer.first,"<?xml version='1.0'?><accepted/>");
            AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box);
            for(vector<HWND>::iterator j = AllHandlers.begin();j!=AllHandlers.end();j++)
                if(SendMessageA(*j, LB_FINDSTRINGEXACT, 0, (LPARAM)Answer.first.c_str())==LB_ERR)
                    SendMessageA(*j, LB_ADDSTRING, 0, (LPARAM)Answer.first.c_str());

            break;

        case 1 :
            AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box);
            for(vector<HWND>::iterator j = AllHandlers.begin();j!=AllHandlers.end();j++)
                if(SendMessageA(*j, LB_FINDSTRINGEXACT, 0, (LPARAM)Answer.first.c_str())==LB_ERR)
                    SendMessageA(*j, LB_ADDSTRING, 0, (LPARAM)Answer.first.c_str());

            break;

        case 2 :
            AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box);
            for(vector<HWND>::iterator j = AllHandlers.begin();j!=AllHandlers.end();j++)
                if((i = SendMessageA(*j, LB_FINDSTRINGEXACT, 0, (LPARAM)Answer.first.c_str()))!=LB_ERR)
                    SendMessageA(*j,LB_DELETESTRING, 0, (LPARAM)Answer.first.c_str());

            break;

        case 3 :

            userReply = MessageBoxW(NULL, L"Принять приглашение на конференцию?",
                    L"", MB_YESNO | MB_ICONQUESTION); 
            if (userReply==IDYES){

                //todo: Проверка на создание встречи, в которой уже состоишь
                string nameOfConf = fetchNameOfInviteConf(Answer.second);
                Pointer->createConference(nameOfConf);
                HWND toSendTo = createMainWindow(Pointer);
                Pointer->setHandlerInfo(nameOfConf,toSendTo);               
                Pointer->addNewMemberToConference_ServerType(nameOfConf,Answer.first);
                string toSend = string("<?xml version='1.0'?><inviteAccepted>") + nameOfConf + string("</inviteAccepted>");
                Pointer->sendMsgToIpUdp(Answer.first,toSend);

            }
            break;

        case 4 :

            string nameOfConf = fetchNameOfInviteAcceptConf(Answer.second);

            toSend.clear();
            Participants.clear();
            Participants = Pointer->getCurrentParticipants(nameOfConf);
            toSend+="<?xml version='1.0'?>";
            toSend+="<conference>";
            toSend+="<nameOfConference>";
            toSend+=nameOfConf;
            toSend+="</nameOfConference>";
            for(vector<string>::iterator i = Participants.begin();i!=Participants.end();i++){
                toSend+="<participant>" + *i + "</participant>";
            }
            toSend+="</conference>";



            Pointer->addNewMemberToConference_ClientType(nameOfConf,Answer.first);

            Pointer->sendToIpTcp(Answer.first,toSend);

            break;

    }
.

receivemsgbyudp () 함수는 메시지를 수신 할 때 까지이 스레드를 중지합니다. 나는 지식이 부족하기 때문에 사과하지만, 어떤 기능을 사용할 수 있는지 또는 다른 것들을 해결할 수 있습니다. My 메소드 receivemsgbyudp ()를 비동기로 재 작성해야합니다. CreateMainWindow () 함수를 메인 스레드에서 실행하려면 어떻게해야합니까? 마지막 변형에 대해 어떻게해야합니까? 마지막 변형에 대해서는 어떻게해야합니까? 순수한 예제를 찾을 수 없었습니다. 누군가가 코드 스 니펫을 줄 수 있습니까? 한 번 더 감사합니다)

도움이 되었습니까?

해결책

주 UI 스레드가 아닌 다른 스레드에서 Windows를 만들 수 있습니다.그러나 이러한 Windows는 이들을 생성 한 스레드에 대한 선호도를 가지며 창을 만드는 모든 스레드에서 메시지 펌프를 실행해야합니다.

그래서 묻는 것을 할 수 있지만 Win32는 동일한 스레드에 대한 친화력을 가진 프로세스에서 모든 창에서 작동하도록 설계되었습니다.여러 개의 UI 스레드를 만드는 데는 실제로 아무 것도 얻지 못할 것입니다.당신이 일하는 데 성공할 것입니다. 당신의 삶을 탁월하고 불필요하게 복잡하게 만드는 것입니다.

다른 팁

"non-main"스레드에서 Windows를 만들 수 있지만 해당 창이 생성 스레드에 연결되어 있으며 메시지 루프를 구현하고 큐에 게시 된 메시지를 계속 보내야합니다. 이렇게하지 않으면 창문이 동결됩니다.

참조 :

  • 메시지 및 메시지 대기열 사용
  • 메시지 처리 - 메시지 정보 및 메시지 대기열

    시스템은 각각에 대한 메시지 큐를 자동으로 생성하지 않습니다. 실. 대신 시스템은 스레드에만 메시지 대기열을 만듭니다. 메시지 대기열이 필요한 작업을 수행합니다. 스레드 인 경우 하나 이상의 Windows를 생성하면 메시지 루프가 제공되어야합니다 ; 이 메시지 루프는 스레드의 메시지 대기열에서 메시지를 검색합니다. 적절한 창 절차에 전달하십시오.

다른 스레드에 창을 만드는 경우 대기중인 메시지가 창을 소유 한 스레드의 메시지 대기열에 게시되어 있으므로 queud 메시지가 게시되어 있으므로 해당 스레드에서 메시지 루프를 구현해야합니다.

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