2015-12-22 32 views
7

sto avendo qualche problema estendendo l'infissi utilizzando DwmExtendFrameIntoClientArea su Windows 10. Le immagini qui sotto mostrano il comportamento sto ottenendo:DwmExtendFrameIntoClientArea strano comportamento su Windows 10

enter image description here

Il colore bianco è barra del titolo esteso dalla parte superiore, mentre dai lati e dal fondo estende il bordo colorato della finestra.

Se fisso i margini tutti -1 estendere le cornici in fondo, la finestra viene riempita con il bianco e perde il suo bordo colorato complessivamente:

enter image description here

Questo risultato è molto incoerente, ero mi aspetto che il colore bianco sia esteso su tutti i lati della finestra, in modo simile al modo in cui la cornice colorata viene estesa in Windows 8, oppure il vetro viene esteso in Windows 7 e Vista.

Ho provato a cercare online, ma non sono stato in grado di trovare problemi simili.

Ecco il codice che sto utilizzando:

#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); 
} 

sto facendo qualcosa di sbagliato o è solo un problema con Windows 10? Grazie in anticipo per qualsiasi aiuto!

Modifica: Il codice che ho postato funziona perfettamente sia con Aero Lite che con i temi ad alto contrasto su Windows 10, ma non con il tema predefinito di Windows 10.

+0

Quasi una buona domanda. Tranne che la domanda è mancante. Per favore, spiega quale dovrebbe essere il risultato atteso. – IInspectable

+1

Mi aspetto che si estenda semplicemente il colore bianco della barra del titolo, simile a come la cornice colorata è estesa su Windows 8, o il vetro su Windows 7 e Vista. Attualmente il risultato è incoerente e sembra solo brutto. – YmFzZTY0

+0

Per favore [modifica] (http://stackoverflow.com/posts/34414751/edit) la tua domanda per includere queste informazioni. – IInspectable

risposta

1

Quando la cornice è stato esteso nella zona del cliente, è necessario assicurarsi che il procedimento di vernice client area attira puro nero ovunque il vetro dovrebbe essere.

Da MSDN:

Il modo più semplice per garantire che le cornici estesi sono visibili è quello di dipingere l'intera regione del nero del cliente. Per eseguire ciò, inizializzare il membro hbrBackground della struttura WNDCLASS o WNDCLASSEX nell'handle dello stock BLACK_BRUSH. L'immagine seguente mostra lo stesso frame standard (a sinistra) e il frame esteso (a destra) mostrati in precedenza. Questa volta, tuttavia, hbrBackground è impostato sull'impugnatura BLACK_BRUSH ottenuta dalla funzione GetStockObject.

enter image description here

Edit: ho cercato di riprodurre più fedelmente il vostro programma scratch possibile:

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. 

e funziona per me:

enter image description here

Qualunque il problema è , il codice non sembra concettualmente sbagliato.

convenzioni Forse chiamata, o un fallimento in cui non si aspetti (RegisterClass per esempio, o l'uso di GetModuleHandle sopra l'istanza maniglia passati a WinMain, o chiamando DwmExtendFrameIntoClientArea anche quando il modulo viene disattivato).

+0

Sto impostando lo sfondo sul nero. Nel codice della mia domanda, riga 21: 'wc.hbrBackground = GetStockObject (BLACK_BRUSH);' – YmFzZTY0

+2

Stai utilizzando il tema Aero Lite. Ho appena testato il mio codice e funziona perfettamente anche con il tema Aero Lite, ma non con il tema standard. – YmFzZTY0