[問題] 使用Win32 API來建立雙視窗

看板C_and_CPP (C/C++)作者 (守護著天使)時間16年前 (2009/08/02 14:48), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
想要利用Win32 API來建立兩個獨立的視窗, 這兩個視窗是可以分別控制,不一定要誰上誰下,且兩個視窗可以互相溝通 目前我拿範例程式來改,有問題(如下): D3DFWSample.exe 中第一個可能發生的例外狀況: 0xC0000005: 寫入位置 0x00000010 時發生存取違規。 請高手幫忙,謝謝!! 或是有什麼資料可以讓我參考~ 以下是程式碼 #include <windows.h> #include "Renderer.h" #include "Scene.h" #define CLIENT_WIDTH 640 #define CLIENT_HEIGHT 480 #define WINDOW_NAME "D3DFWSample" // 視窗名稱 #define WINDOW_NAME2 "D3DFWSample2" // 視窗名稱2 LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK WindowProc2(HWND hWnd2, UINT msg2, WPARAM wParam2, LPARAM lParam2); //------------------------------------------------------------- // 應用程式的進入點 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char clsName[] = "D3DFWSampleClass"; // 視窗類別名稱 char clsName2[] = "D3DFWSampleClass2"; // 視窗類別名稱2 HWND hWnd; MSG msg; HWND hWnd2; MSG msg2; // 視窗類別初始化 WNDCLASSEX wcex = { sizeof(WNDCLASSEX), NULL, WindowProc, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, clsName, NULL }; // 視窗類別初始化2 WNDCLASSEX wcex2 = { sizeof(WNDCLASSEX), NULL, WindowProc2, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, clsName2, NULL }; // 視窗類別的登錄 if(RegisterClassEx(&wcex) == 0){ return 0; //登錄失敗 } // 視窗類別的登錄2 if(RegisterClassEx(&wcex2) == 0){ return 0; //登錄失敗 } // 產生視窗 if(isFullScreen) { // 全螢幕 int sw; int sh; // 取得畫面的寬與高 sw = GetSystemMetrics(SM_CXSCREEN); sh = GetSystemMetrics(SM_CYSCREEN); hWnd = CreateWindow( clsName, WINDOW_NAME, WS_POPUP, 0, 0, CLIENT_WIDTH, CLIENT_HEIGHT, NULL, NULL, hInstance, NULL ); } else { hWnd = CreateWindow(clsName, WINDOW_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); // 重設視窗的大小 RECT rect; int ww, wh; int cw, ch; GetClientRect(hWnd, &rect); // 取得用戶端部份大小 cw = rect.right - rect.left; // 計算用戶端區域以外的寬度 ch = rect.bottom - rect.top; // 計算用戶端區域以外的高度 GetWindowRect(hWnd, &rect); // 取得整體視窗的大小 ww = rect.right - rect.left; // 計算整體視窗的寬度 wh = rect.bottom - rect.top; // 計算整體視窗的高度 ww = ww - cw; // 用戶端區域以外所需要的寬度 wh = wh - ch; // 用戶端區域以外所需要的高度 // 再計算視窗的大小 ww = CLIENT_WIDTH + ww; // 必要的視窗寬度 wh = CLIENT_HEIGHT + wh; // 必要的視窗高度 // 再設定視窗的大小 SetWindowPos(hWnd, HWND_TOP, 0, 0, ww, wh, SWP_NOMOVE); } // 產生視窗2 if(isFullScreen) { // 全螢幕 int sw; int sh; // 取得畫面的寬與高 sw = GetSystemMetrics(SM_CXSCREEN); sh = GetSystemMetrics(SM_CYSCREEN); hWnd2 = CreateWindow( clsName2, WINDOW_NAME2, WS_POPUP, 0, 0, CLIENT_WIDTH, CLIENT_HEIGHT, NULL, NULL, hInstance, NULL ); } else { hWnd2 = CreateWindow(clsName2, WINDOW_NAME2, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); // 重設視窗的大小 RECT rect; int ww, wh; int cw, ch; GetClientRect(hWnd2, &rect); // 取得用戶端部份大小 cw = rect.right - rect.left; // 計算用戶端區域以外的寬度 ch = rect.bottom - rect.top; // 計算用戶端區域以外的高度 // 計算整個視窗的橫向寬度 GetWindowRect(hWnd2, &rect); // 取得整體視窗的大小 ww = rect.right - rect.left; // 計算整體視窗的寬度 wh = rect.bottom - rect.top; // 計算整體視窗的高度 ww = ww - cw; // 用戶端區域以外所需要的寬度 wh = wh - ch; // 用戶端區域以外所需要的高度 // 再計算視窗的大小 ww = CLIENT_WIDTH + ww; // 必要的視窗寬度 wh = CLIENT_HEIGHT + wh; // 必要的視窗高度 // 再設定視窗的大小 SetWindowPos(hWnd2, HWND_TOP, 0, 0, ww, wh, SWP_NOMOVE); } // 顯示視窗 ShowWindow(hWnd, nCmdShow); // 顯示視窗2 ShowWindow(hWnd2, nCmdShow); // 使WM_PAINT不被呼叫 ValidateRect(hWnd, 0); // 使WM_PAINT不被呼叫 ValidateRect(hWnd2, 0); // renderer物件 Renderer renderer; // renderer物件2 Renderer renderer2; // renderer初始化 HRESULT hr; hr = renderer.Initialize(hWnd, isFullScreen, CLIENT_WIDTH, CLIENT_HEIGHT); if(FAILED(hr)) { return 0; // 初始化失敗 } // renderer初始化2 HRESULT hr2; hr2 = renderer.Initialize(hWnd2, isFullScreen, CLIENT_WIDTH, CLIENT_HEIGHT); if(FAILED(hr2)) { return 0; // 初始化失敗 } // 場景(scene)物件 Scene scene; // 場景(scene)物件2 Scene scene2; // 產生場景 if(FAILED(scene.Create(renderer.GetDevice()))) { return 0; } // 產生場景2 if(FAILED(scene2.Create(renderer2.GetDevice()))) { return 0; } // 訊息處理以及描繪迴圈 while(TRUE) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) { break; // 迴圈結束 } else { // 訊息的翻譯以及Dispatch TranslateMessage(&msg); DispatchMessage(&msg); } } else { // 若無處理訊息時進行描繪 // 只有在看到視窗時描繪的處理 WINDOWPLACEMENT wndpl; GetWindowPlacement(hWnd, &wndpl); if((wndpl.showCmd != SW_HIDE) && (wndpl.showCmd != SW_MINIMIZE) && (wndpl.showCmd != SW_SHOWMINIMIZED) && (wndpl.showCmd != SW_SHOWMINNOACTIVE)) { // 執行描繪處理 renderer.RenderScene(&scene); } } Sleep(1); } // 訊息處理以及描繪迴圈2 while(TRUE) { if(PeekMessage(&msg2, NULL, 0, 0, PM_REMOVE)) { if(msg2.message == WM_QUIT) { break; // 迴圈結束 } else { // 訊息的翻譯以及Dispatch TranslateMessage(&msg2); DispatchMessage(&msg2); } } else { // 若無處理訊息時進行描繪 // 只有在看到視窗時描繪的處理 WINDOWPLACEMENT wndpl2; GetWindowPlacement(hWnd2, &wndpl2); if((wndpl2.showCmd != SW_HIDE) && (wndpl2.showCmd != SW_MINIMIZE) && (wndpl2.showCmd != SW_SHOWMINIMIZED) && (wndpl2.showCmd != SW_SHOWMINNOACTIVE)) { // 執行描繪處理 renderer2.RenderScene(&scene2); } } Sleep(1); } return (int) msg.wParam; } //------------------------------------------------------------- // 訊息處理所使用的Callback //------------------------------------------------------------- LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CLOSE: // 視窗被關閉 PostQuitMessage(0); // 結束應用程式 break; case WM_KEYDOWN: // 有鍵被按下 if (wParam == VK_ESCAPE) { // 被按下的是ESC鍵 PostQuitMessage(0); // 結束應用程式 } break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; } LRESULT CALLBACK WindowProc2(HWND hWnd2, UINT msg2, WPARAM wParam2, LPARAM lParam2) { switch (msg2) { case WM_CLOSE: // 視窗被關閉 PostQuitMessage(0); // 結束應用程式 break; case WM_KEYDOWN: // 有鍵被按下 if (wParam2 == VK_ESCAPE) { // 被按下的是ESC鍵 PostQuitMessage(0); // 結束應用程式 } break; default: return DefWindowProc(hWnd2, msg2, wParam2, lParam2); } return 0; } -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.135.180.252 ※ 編輯: xxx1118 來自: 140.96.76.126 (08/04 11:10)
文章代碼(AID): #1ATJR2VO (C_and_CPP)
文章代碼(AID): #1ATJR2VO (C_and_CPP)