Привет всем... Запутался в такой ситуауии... Программа, вначале регистрирует свой класс окна, создаёт окно ну и дальше, как обычно, имеет свою функцию обработки сообщений... У окна есть кнопка при нажатии на которую вызывается функция в которой создаётся новый класс окна, новое окно с кнопкой и процедура обработки сообщений тоже новая. Вопрос как сделать так, чтобы пользователю было запрещено при вызове второго окна переключиться на первое, предварительно не закрыв его или не нажав кнопку (диалог использовать нельзя). Код (Text): #include "stdafx.h" #include <windows.h> LRESULT CALLBACK WindowFunc_1 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK WindowFunc_2 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); char szWinName_1[] = "MyApp_1"; char szWinName_2[] = "MyApp_2"; HWND hMain_1, hButton_1, hMain_2, hButton_2; VOID MyFunc () { MSG Msg; WNDCLASSEX wc = {0}; wc.hInstance = GetModuleHandle (NULL); wc.lpszClassName = szWinName_2; wc.lpfnWndProc = WindowFunc_2; wc.style = CS_SAVEBITS | CS_DBLCLKS; wc.cbSize = sizeof(WNDCLASSEX); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszMenuName = NULL; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = GetSysColorBrush (COLOR_3DFACE); RegisterClassEx(&wc); hMain_2 = CreateWindowEx (WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT, szWinName_2, "Не главное окно", WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_3DLOOK | DS_SETFONT | DS_MODALFRAME, 350, 350, 400, 400, hMain_1, NULL, GetModuleHandle (NULL), NULL); ShowWindow (hMain_2, SW_SHOW), UpdateWindow (hMain_2); hButton_2 = CreateWindow ("BUTTON", "OK", WS_VISIBLE|WS_CHILD, 150, 150, 90, 30, hMain_2, NULL, GetModuleHandle (NULL), NULL); ShowWindow(hButton_2,SW_SHOW), UpdateWindow(hButton_2); while(GetMessage(&Msg, NULL,0,0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } UnregisterClass (szWinName_2, GetModuleHandle (NULL)); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) { MSG Msg; WNDCLASSEX wc = {0}; wc.hInstance = GetModuleHandle (NULL); wc.lpszClassName = szWinName_1; wc.lpfnWndProc = WindowFunc_1; wc.style = CS_SAVEBITS | CS_DBLCLKS; wc.cbSize = sizeof(WNDCLASSEX); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszMenuName = NULL; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = GetSysColorBrush (COLOR_3DFACE); RegisterClassEx(&wc); hMain_1 = CreateWindowEx (WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT, szWinName_1, "Главное окно", WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_3DLOOK | DS_SETFONT | DS_MODALFRAME, 300, 300, 400, 400, HWND_DESKTOP, NULL, GetModuleHandle (NULL), NULL); ShowWindow (hMain_1, SW_SHOW), UpdateWindow (hMain_1); hButton_1 = CreateWindow ("BUTTON", "OK", WS_VISIBLE|WS_CHILD, 150, 150, 90, 30, hMain_1, NULL, GetModuleHandle (NULL), NULL); ShowWindow(hButton_1,SW_SHOW), UpdateWindow(hButton_1); while(GetMessage(&Msg, NULL,0,0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } UnregisterClass (szWinName_1, GetModuleHandle (NULL)); } LRESULT CALLBACK WindowFunc_1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; static HDC hdc; switch(message) { case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case BN_CLICKED: if (hButton_1 == (HWND)lParam) { MyFunc (); MessageBox (0, "1", "1", 0); } } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } LRESULT CALLBACK WindowFunc_2(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; static HDC hdc; switch(message) { case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case BN_CLICKED: if (hButton_2 == (HWND)lParam) MessageBox (0, "2", "2", 0); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
Ага, я тоже с этим сталкивался. Изучил как это делается в диалогах. В итоге пришёл к выводу, что нужно в WM_CREATE нового окна выполнять EnableWindow(FALSE) по хендлу своего родителя. А при WM_CLOSE - тем же макаром разблокировать.
Ага правильно так и сделал в обработчике нажатия кнопки в главном окне сделал так: Код (Text): case WM_COMMAND: switch (LOWORD(wParam)) { case BN_CLICKED: if (hButton_1 == (HWND)lParam) { EnableWindow (hMain_1, FALSE); MyFunc (); } } break; А в функции обработчике не главного окна сделал так: Код (Text): case WM_COMMAND: switch (LOWORD(wParam)) { case BN_CLICKED: if (hButton_2 == (HWND)lParam) EnableWindow (hMain_1, TRUE); DestroyWindow (hMain_2); } break; Переключения не происходит и при надатии на кнопку окно закрывается и делает активным главное... То же самое написал и для обработчика сообщения WM_CLOSE: Код (Text): case WM_CLOSE: EnableWindow (hMain_1, TRUE); DestroyWindow (hMain_2); Вроде всё верно сделал, так?
Для птичьих языков програмирования есть специальный раздел, а для НАЧИНАЮЩИХ писать на птичьих языках - специальные сайты
GetWindowRect Дальше там посчитаешь сам (составляешь 2 уравнения и считаешь новые координаты и указываешь их при создании окна, или двигаешь с помощью SetWindowPos)
Vilco сделал так... Код (Text): int iWinX1 = 600, iWinY1 = 600; // для главного окна int iWinX2 = 300, iWinY2 = 300; // для дочернего окна // для главного окна hMain = CreateWindowEx (WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT, szMainClass, "BMP Counter 8.0", WS_CAPTION | WS_VISIBLE | WS_SYSMENU, GetSystemMetrics (SM_CXSCREEN)/2-iWinX/2, GetSystemMetrics (SM_CYSCREEN)/2-iWinY/2, iWinX, iWinY, HWND_DESKTOP, NULL, hThisInst, NULL); // а для дочернего окна делаю так POINT point; point.x = iWinX/2 - iWinX2/2; point.y = iWinY/2 - iWinY2/2; ClientToScreen (hMain, &point); // создание дочернего окна CreateWindowEx (WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT, szAboutClass, "Дочернее окно", WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_SYSMENU | DS_MODALFRAME, point.x, point.y, iWinX2, iWinY2, hMain, NULL, GetModuleHandle (NULL), NULL); Проблема в том что неправильно выравнивает по вертикали, так как ширина окна без учёта меню и заголовка... Тогда как же программно узнать полные размеры окна?