Mam funkcję:Tworzenie okna w innym wątku (nie główny wątek)
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;
}
I to jest główną częścią mojego programu:
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;
gdy zgłoszę funkcja createMainWindow() w głównej części mojego programu działa tak, jak powinien, ale gdy uruchomię go w mój wątek (ClientThread) nie działa. Czytałem, że powinienem tworzyć okna tylko w głównym wątku. Czy to prawda? A jeśli to prawda, jaki jest najprostszy sposób wywoływania tej funkcji od innego theada w głównym wątku?
Dziękuję wszystkim. Teraz znam problem, ale utknąłem z rozwiązaniem. Mój klient kod wątku jest:
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 function() zatrzymuje ten wątek aż otrzyma wiadomość. Przepraszam za brak wiedzy, ale jakie funkcje mogę użyć lub inne rzeczy, aby to rozwiązać. Czy powinienem przepisać metodę receiveMsgByUdp() na asynchroniczną lub jak mogę wywołać funkcję createMainWindow() do uruchomienia w głównym wątku? O ostatnim wariancie: jak mogę to zrobić w czystej winapi, nie mogłem znaleźć żadnych prostych przykładów. Czy ktoś może podać fragment kodu? Jeszcze raz dziękuję)
Dzięki wszystkim.Udało mi się uruchomić ten program. użyłem metody Davida Heffernana. I informacje na ten link http://stackoverflow.com/questions/7060686/how-do-i-sendmessage-to-a-window-created-on-another-thread – knightOfSpring