2015-12-22 24 views
7

Tôi đang gặp một số rắc rối kéo dài khung cửa sổ bằng DwmExtendFrameIntoClientArea trên Windows 10. Các hình ảnh dưới đây cho thấy hành vi tôi nhận được:DwmExtendFrameIntoClientArea hành vi lạ trên Windows 10

enter image description here

Màu trắng là titlebar mở rộng từ trên xuống, trong khi từ các cạnh và đáy nó mở rộng cạnh màu của cửa sổ.

Nếu tôi đặt bên lề tất cả để -1 để mở rộng khung tất cả các cách, các cửa sổ được làm đầy với màu trắng và mất lợi thế cạnh màu của nó hoàn toàn:

enter image description here

Kết quả này là rất phù hợp, tôi đã mong đợi màu trắng sẽ được mở rộng trên tất cả các cạnh của cửa sổ, tương tự như cách khung màu được mở rộng trong Windows 8, hoặc kính được mở rộng trong Windows 7 và Vista.

Tôi đã thử tìm kiếm trực tuyến nhưng tôi chưa thể tìm thấy bất kỳ vấn đề tương tự nào.

Dưới đây là đoạn code Tôi đang sử dụng:

#include <windows.h> 
#include <dwmapi.h> 
#include <stdio.h> 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 

int main(int argc, char **argv) 
{ 

    HINSTANCE hInstance = GetModuleHandle(NULL); 
    MSG msg;  
    HWND hwnd; 
    WNDCLASSW wc; 
    int message; 

    wc.style   = CS_HREDRAW | CS_VREDRAW; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.lpszClassName = L"Window"; 
    wc.hInstance  = hInstance; 
    wc.hbrBackground = GetStockObject(BLACK_BRUSH); 
    wc.lpszMenuName = NULL; 
    wc.lpfnWndProc = WndProc; 
    wc.hCursor  = LoadCursor(NULL, IDC_ARROW); 
    wc.hIcon   = LoadIcon(NULL, IDI_APPLICATION); 

    RegisterClassW(&wc); 
    hwnd = CreateWindowW(wc.lpszClassName, L"Window", 
         WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
         100, 100, 350, 250, NULL, NULL, hInstance, NULL); 

    ShowWindow(hwnd, SW_SHOW); 
    UpdateWindow(hwnd); 

    while(1) { 
     message = GetMessageW(&msg, NULL, 0, 0); 
     if(message == -1) 
     { 
      char x[100]; 
      FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 
          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), x, 100, NULL); 
      puts(x); 
      abort(); 
     } 
     else if(message == 0) break; 

     TranslateMessage(&msg); 
     DispatchMessageW(&msg); 
    } 

    return (int) msg.wParam; 
} 

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(msg) 
    { 
     case WM_ACTIVATE: 
     { 
      MARGINS m = {50, 50, 50, 50}; 
      HRESULT hr = DwmExtendFrameIntoClientArea(hwnd, &m); 
      if(!SUCCEEDED(hr)) 
      { 
       char x[100]; 
       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 
           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), x, 100, NULL); 
       puts(x); 
       abort(); 
      } 
      break; 
     } 
     case WM_DESTROY: 
      PostQuitMessage(0); 
      return 0;  
    } 

    return DefWindowProcW(hwnd, msg, wParam, lParam); 
} 

Tôi có làm gì sai hay là này chỉ là một vấn đề với Windows 10? Cảm ơn trước sự giúp đỡ nào!

Chỉnh sửa: Mã tôi đã đăng hoạt động hoàn hảo với cả Aero Lite và các chủ đề có độ tương phản cao trên Windows 10, nhưng không có chủ đề Windows 10 mặc định.

+0

Hầu như là một câu hỏi hay. Ngoại trừ, câu hỏi bị thiếu. Xin giải thích, kết quả mong đợi là gì. – IInspectable

+1

Tôi hy vọng nó chỉ đơn giản là mở rộng màu trắng của thanh tiêu đề, tương tự như cách khung màu được mở rộng trên Windows 8, hoặc kính trên Windows 7 & vista. Hiện tại, kết quả là không nhất quán và chỉ trông xấu xí. – YmFzZTY0

+0

Vui lòng [edit] (http://stackoverflow.com/posts/34414751/edit) câu hỏi của bạn để bao gồm thông tin này. – IInspectable

Trả lời

1

Khi khung đã được mở rộng vào khu vực của khách hàng, bạn cần phải chắc chắn rằng thủ tục sơn khu vực khách hàng của bạn thu hút tinh khiết đen bất cứ nơi nào kính nên.

Từ MSDN:

Cách dễ nhất để đảm bảo rằng các khung mở rộng có thể nhìn thấy là để sơn toàn bộ khu vực khách hàng đen. Để thực hiện việc này, hãy khởi tạo thành viên hbrBackground của cấu trúc WNDCLASS hoặc WNDCLASSEX của bạn tới tay cầm của cổ phiếu BLACK_BRUSH. Hình ảnh sau đây cho thấy cùng một khung tiêu chuẩn (bên trái) và khung mở rộng (bên phải) được hiển thị trước đó. Tuy nhiên, thời gian này, hbrBackground được đặt thành núm điều khiển BLACK_BRUSH thu được từ chức năng GetStockObject.

enter image description here

Sửa: Tôi cố gắng để tái tạo chương trình đầu của bạn càng sát càng tốt:

program ScratchProgram; 

uses 
    Windows, 
    Messages, 
    DwmApi, 
    UxTheme; 

{ Window Procedure } 
function WndProc(hWnd: HWND; uiMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; 
var 
    m: TMargins; 
begin 
    case uiMsg of 
    WM_ACTIVATE: 
     begin 
      m.cxLeftWidth := 50; 
      m.cxRightWidth := 50; 
      m.cyTopHeight := 50; 
      m.cyBottomHeight := 50; 
      DwmExtendFrameIntoClientArea(hWnd, m); 
     end; 
    WM_DESTROY: 
     begin 
      PostQuitMessage(0); 
      Result := 0; 
      Exit; 
     end; 
    end; 

    Result := DefWindowProc(hWnd, uiMsg, wParam, lParam); 
end; 

function WinMain(hInstance: HINST; hPrevInstance: HINST; lpCmdLine: PChar; nShowCmd: Integer): Integer; stdcall; 
var 
    wc: WNDCLASS; 
    msg: TMSG; 
    hWindow: HWND; 
    instance: HINST; 
begin 
    instance := GetModuleHandle(nil); 

    wc.style := CS_HREDRAW or CS_VREDRAW; 
    wc.cbClsExtra := 0; 
    wc.cbWndExtra := 0; 
    wc.lpszClassName := 'Window'; 
    wc.hInstance := instance; 
    wc.hbrBackground := GetStockObject(BLACK_BRUSH); 
    wc.lpszMenuName := nil; 
    wc.lpfnWndProc := @WndProc; 
    wc.hCursor := LoadCursor(0, IDC_ARROW); 
    wc.hIcon := LoadIcon(0, IDI_APPLICATION); 

    RegisterClass(wc); 

    hWindow := CreateWindow(
      wc.lpszClassName,     // Class Name 
      'Window',       // Title 
      WS_OVERLAPPEDWINDOW or WS_VISIBLE, // Style 
      100, 100,       // Position 
      350, 250,       // Size 
      0,         // Parent 
      0,         // No menu 
      instance,       // Instance 
      nil);        // No special parameters 

    ShowWindow(hWindow, SW_SHOW); 

    while (GetMessage(msg, 0, 0, 0)) do 
    begin 
     TranslateMessage(msg); 
     DispatchMessage(msg); 
    end; 

    Result := 0; 
end; 

begin 
    WinMain(hInstance, hPrevInst, CmdLine, CmdShow); 
end. 

Và nó làm việc cho tôi:

enter image description here

Dù vấn đề là , mã không nhìn khái niệm sai.

ước Có lẽ gọi điện thoại, hoặc một sự thất bại mà bạn không mong đợi nó (RegisterClass ví dụ, hay việc sử dụng các GetModuleHandle qua instance handle truyền cho WinMain, hoặc gọi DwmExtendFrameIntoClientArea ngay cả khi các hình thức đã được ngừng hoạt động).

+0

Tôi đang đặt nền thành màu đen. Trong mã trong câu hỏi của tôi, dòng 21: 'wc.hbrBackground = GetStockObject (BLACK_BRUSH);' – YmFzZTY0

+2

Bạn đang sử dụng chủ đề Aero Lite. Tôi chỉ thử nghiệm mã của tôi và nó hoạt động hoàn hảo với chủ đề Aero Lite quá, nhưng vẫn không với chủ đề tiêu chuẩn. – YmFzZTY0