2010-02-28 27 views
7

Tôi đang đọc Introduction to 3D Game Programming with DirectX 10 để tìm hiểu một số DirectX và tôi đang cố gắng thực hiện các bài tập được đề xuất (chương 4 cho những người có sách).Vô hiệu hóa alt-enter trong ứng dụng Direct3D (DirectX)

Một bài tập yêu cầu tắt chức năng Alt + Enter (chuyển đổi chế độ toàn màn hình) bằng cách sử dụng IDXGIFactory::MakeWindowAssociation.

Tuy nhiên, nó vẫn chuyển sang chế độ toàn màn hình và tôi không thể hiểu tại sao. Đây là mã của tôi:

HR(D3D10CreateDevice(
     0,     //default adapter 
     md3dDriverType, 
     0,     // no software device 
     createDeviceFlags, 
     D3D10_SDK_VERSION, 
     &md3dDevice)); 

IDXGIFactory *factory; 
HR(CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&factory)); 
HR(factory->CreateSwapChain(md3dDevice, &sd, &mSwapChain)); 
factory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_ALT_ENTER); 
ReleaseCOM(factory); 
+0

MakeWindowAssociation trả về một HRESULT để bọc HR() xung quanh cuộc gọi đó cũng như để xem nếu nó không thành công vì một lý do nào đó. (Chỉ cần một phụ lưu ý, tôi không nghĩ rằng nó thực sự thất bại) –

+0

@Danial: đã cố gắng, không có may mắn. Tôi sẽ bắt đầu một tiền thưởng chỉ cho heck của nó mặc dù. –

Trả lời

9

Tôi nghĩ vấn đề là vậy.

Vì bạn tự tạo thiết bị (và không phải thông qua nhà máy), bất kỳ cuộc gọi nào được thực hiện đối với nhà máy bạn đã tạo sẽ không thay đổi bất kỳ thứ gì.

Vì vậy, hoặc là bạn:

a) Tạo các nhà máy sớm hơn và tạo ra các thiết bị thông qua nó

HOẶC

b) Lấy nhà máy thực tế sử dụng để tạo ra các thiết bị thông qua các mã dưới đây.

IDXGIDevice * pDXGIDevice; 
HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice)); 

IDXGIAdapter * pDXGIAdapter; 
HR(pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter)); 

IDXGIFactory * pIDXGIFactory; 
pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&pIDXGIFactory); 

Và gọi hàm thông qua nhà máy đó (sau khi SwapChain đã được tạo ra)

pIDXGIFactory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_ALT_ENTER); 

MSDN: IDXGIFactory

+0

Tôi đã thử điều đó (tôi đã googling một lúc); tiếc là nó không hoạt động. Tất cả các cuộc gọi đều thành công nhưng tab alt vẫn tối đa hóa cửa sổ. –

+0

Lạ, tôi đã thử mã của bạn và khi sử dụng nhà máy đã được sử dụng để tạo thiết bị nó hoạt động cho tôi. Đây là mã của bạn được viết lại, trong trường hợp có điều gì đó không rõ ràng trong câu trả lời của tôi: http://pastebin.com/sz2YzdZf –

+0

Sử dụng cùng mã chính xác mà bạn đăng trên pastebin alt-enter vẫn tối đa hóa cửa sổ. Đây là mã chính xác tôi đã sử dụng: http://koper.wowpanda.net/directx-code.rar –

1

Tôi có cùng một vấn đề, và

b) Lấy nhà máy thực sự được sử dụng để tạo thiết bị thông qua mã bên dưới.

cũng không giúp ích gì cho tôi, có thể vì tôi có nhiều cửa sổ Direct3D10 nhưng IDXGIFactory :: MakeWindowAssociation nhớ nó chỉ dành cho một. Nhưng việc gọi hàm trên WM_SETFOCUS hoặc WM_ACTIVATE cũng không giúp ích được vì lý do không xác định.

Vì vậy, một cách tôi tìm thấy là sử dụng móc bàn phím cấp thấp: xem SetWindowsHookEx với thông số WH_KEYBOARD_LL. Sau đó bạn có thể nắm bắt Alt + Enter bằng mã ảo VK_RETURN với điều kiện (VK_LMENU | VK_RMENU | VK_MENU) đã được nhấn. Sau khi bạn nhận ra tình huống này chỉ cần trả về 1 thay vì gọi hàm CallNextHookEx.

+0

Và đừng quên làm điều này chỉ cho cửa sổ của bạn, bởi vì móc mặc định sẽ được cài đặt cho toàn bộ hệ thống. 1. Ví dụ bạn có thể cài đặt móc khi quá trình của bạn hoạt động và gỡ cài đặt khi nó ngừng hoạt động (xem thông báo WM_ACTIVATEAPP). 2. Hoặc bạn có thể kiểm tra trong móc nếu cửa sổ tiền cảnh là cửa sổ của bạn (xem chức năng GetForegroundWindow WinAPI) –

+0

Bạn sẽ không gọi hàm MakeWindowAssociation() mỗi khi thiết bị mới được tạo ra? Hoặc tạo IDXGIFactory cho mỗi? –

Các vấn đề liên quan