Anonymous
Создание окна в другом потоке (не в основном потоке)
Сообщение
Anonymous » 14 янв 2025, 13:59
У меня есть функция:
Код: Выделить всё
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)
{
coutisMyLocalAddress(Answer.first)){
int type = messageUdpContentType(Answer.second);
switch(type){
case 0 :
Pointer->sendMsgToIpUdp(Answer.first,"");
AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box);
for(vector::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::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::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("") + nameOfConf + string("");
Pointer->sendMsgToIpUdp(Answer.first,toSend);
}
break;
case 4 :
string nameOfConf = fetchNameOfInviteAcceptConf(Answer.second);
toSend.clear();
Participants.clear();
Participants = Pointer->getCurrentParticipants(nameOfConf);
toSend+="";
toSend+="";
toSend+="";
toSend+=nameOfConf;
toSend+="";
for(vector::iterator i = Participants.begin();i!=Participants.end();i++){
toSend+="
" + *i + "";
}
toSend+="";
Pointer->addNewMemberToConference_ClientType(nameOfConf,Answer.first);
Pointer->sendToIpTcp(Answer.first,toSend);
break;
}
функция getMsgByUdp() останавливает этот поток до тех пор, пока не получит сообщение. Прошу прощения за недостаток знаний, но какие функции я могу использовать или что-то еще, чтобы решить эту проблему. Должен ли я переписать свой метод получения MsgByUdp(), чтобы он был асинхронным, или как я могу вызвать функцию createMainWindow() для запуска в основном потоке? О последнем варианте: как я могу сделать это в чистом WinAPI, я не смог найти простых примеров. Может кто-нибудь дать фрагмент кода. Спасибо еще раз)
Подробнее здесь:
https://stackoverflow.com/questions/965 ... ain-thread
1736852389
Anonymous
У меня есть функция: [code]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; } [/code] И это основная часть моей программы: [code]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) { coutisMyLocalAddress(Answer.first)){ int type = messageUdpContentType(Answer.second); switch(type){ case 0 : Pointer->sendMsgToIpUdp(Answer.first,""); AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box); for(vector::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::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::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("") + nameOfConf + string(""); Pointer->sendMsgToIpUdp(Answer.first,toSend); } break; case 4 : string nameOfConf = fetchNameOfInviteAcceptConf(Answer.second); toSend.clear(); Participants.clear(); Participants = Pointer->getCurrentParticipants(nameOfConf); toSend+=""; toSend+=""; toSend+=""; toSend+=nameOfConf; toSend+=""; for(vector::iterator i = Participants.begin();i!=Participants.end();i++){ toSend+=" " + *i + ""; } toSend+=""; Pointer->addNewMemberToConference_ClientType(nameOfConf,Answer.first); Pointer->sendToIpTcp(Answer.first,toSend); break; } [/code] функция getMsgByUdp() останавливает этот поток до тех пор, пока не получит сообщение. Прошу прощения за недостаток знаний, но какие функции я могу использовать или что-то еще, чтобы решить эту проблему. Должен ли я переписать свой метод получения MsgByUdp(), чтобы он был асинхронным, или как я могу вызвать функцию createMainWindow() для запуска в основном потоке? О последнем варианте: как я могу сделать это в чистом WinAPI, я не смог найти простых примеров. Может кто-нибудь дать фрагмент кода. Спасибо еще раз) Подробнее здесь: [url]https://stackoverflow.com/questions/9654532/creating-window-in-another-threadnot-main-thread[/url]