سؤال

لقد حصلت على وظيفة:

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) لا يعمل.لقد قرأت أنه يجب علي إنشاء النوافذ في الموضوع الرئيسي فقط.هل هذا صحيح؟وإذا كان هذا صحيحًا، ما هي أبسط طريقة لاستدعاء هذه الوظيفة من موضوع آخر في الموضوع الرئيسي؟


شكرا لكم جميعا.الآن أعرف المشكلة، لكني عالق في الحل.رمز موضوع العميل الخاص بي هو:

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;

    }

تقوم الدالةrecemMsgByUdp() بإيقاف هذا الموضوع حتى تتلقى الرسالة.أعتذر عن قلة المعرفة، ولكن ما هي الوظائف التي يمكنني استخدامها أو أشياء أخرى لحل هذه المشكلة.هل يجب علي إعادة كتابة طريقتي getMsgByUdp() لتكون غير متزامنة أو كيف يمكنني استدعاء الوظيفة createMainWindow() ليتم تشغيلها على مؤشر الترابط الرئيسي؟ حول المتغير الأخير:كيف يمكنني القيام بذلك في برنامج Winapi النقي، لم أتمكن من العثور على أي أمثلة بسيطة.يمكن لأي شخص أن يعطي مقتطف التعليمات البرمجية.شكرا مرة أخرى)

هل كانت مفيدة؟

المحلول

يمكنك بالفعل إنشاء Windows في خيوط أخرى غير مؤشر ترابط UI الرئيسي.ومع ذلك، فإن هذه النوافذ سيكون لها تقارب للخيط الذي قمت بإنشائه وستحتاج إلى تشغيل مضخة رسالة في كل مؤشر ترابط يخلق Windows.

لذلك يمكنك القيام بما تسأله، ويحتوي Win32 مصممة حقا للعمل مع جميع النوافذ في عملية وجود تقارب إلى نفس الخيط.لا يوجد في الحقيقة من إنشاء مؤشرات ترابط UI متعددة.كل ما ستنجح فيه في القيام به هو جعل حياتك معقدة بشكل غير عادي ولا داعي لها.

نصائح أخرى

يمكنك إنشاء نوافذ على سلاسل الرسائل "غير الرئيسية" ولكن انتبه إلى أن هذه النوافذ متصلة بسلسلة الإنشاء، وتحتاج إلى التأكد من تنفيذ حلقة رسائل هناك والاستمرار في إرسال الرسائل المنشورة في قائمة الانتظار.إذا لم تقم بذلك، فسوف تتجمد نوافذك.

يرى:

لا يقوم النظام تلقائيا بإنشاء قائمة انتظار رسائل لكل منها خيط.بدلا من ذلك، يقوم النظام بإنشاء قائمة انتظار رسائل فقط لسلاسل الرسائل التي تنفذ العمليات التي تتطلب قائمة انتظار رسائل. إذا كان الموضوع ينشئ نافذة واحدة أو أكثر ، يجب توفير حلقة رسالة;هذا تقوم حلقة الرسائل باسترداد الرسائل من قائمة انتظار رسائل سلسلة الرسائل و يرسلهم إلى إجراءات النافذة المناسبة.

إذا قمت بإنشاء نافذة في مؤشر ترابط آخر، فستحتاج أيضا إلى تطبيق حلقة للرسائل على هذا الموضوع نظرا لاستكشاف رسائل في قائمة الانتظار في قائمة انتظار الرسائل التي تمتلك النافذة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top