Можете ли вы создать главное окно приложения без полей в Windows без стиля WS_POPUP? - PullRequest
8 голосов
/ 04 февраля 2011

Я хочу создать окно, которое будет основным окном и которое сама Windows распознает как главное окно приложения.Однако, когда я делаю свое окно без границ и вообще без какой-либо клиентской области, Windows больше не распознает, что это окно является главным окном приложения.Это имеет несколько побочных эффектов:

  1. WindowsKey + M сворачивает все окна, кроме главного окна моего приложения.

  2. Один клик на панели задач (в win7), а затем снова должен переключить состояние / видимость главного окна приложения между нормальным и свернутым состоянием.Это не работает для такого окна.

В простых терминах программирования Win32 я спрашиваю о значениях параметров для dwStyle , как при вызове CreateWindow (константы WS _...) или CreateWindowEx (константы WS_EX _...).Для пользователей Delphi эти значения будут установлены в методе CreateParams, который вы должны переопределить, а затем установить Params.Style: = WS_xxx;Для пользователей MFC / C ++ и пользователей C что-то в вашей среде в конечном итоге будет вызывать CreateWindow с этим значением dwStyle.

В терминах delphi установка form.BorderStyle = bsNone приводит к dwStyle = WS_POPUP.Однако мне нужно окно без полей без использования dwStyle = WS_POPUP.

Примечание. Все ответы ниже хороши, но использование каждого из них в производственных сценариях проблематично, и мои попытки сделать это привели к множеству глюков,что для профессионального качества приложения, я до сих пор не могу обойтись.Ответ Davids - это отличный чистый ответ Win32 API, и он отвечает всем требованиям.Кажется, что промышленное решение должно сочетать в себе множество качеств, в том числе все те, которые у меня есть в моем вопросе выше.Короче говоря, формы без полей с использованием BorderStyle = bsNone (dwStyle = WS_POPUP) блокируют все функциональные возможности Windows, которые обычно применяются к основным окнам приложений, и все приведенные ниже решения решают часть этого.

Основываясь на предложениях Дэвида, я написал следующее, что не работает: я хочу окно без рамки, которое ведет себя во всех отношениях, как окно приложения Windows, к системе, то есть ономожно свернуть / восстановить, щелкнув окно в панели задач, и свернуть с помощью WindowsKey + M.Я начинаю думать, что единственный способ сделать это состоит в том, чтобы добавить не-клиентский код рисования и изменить размеры верхних границ не-клиентской области до нуля.Это, конечно, не тривиальная идея.

Оказывается, я допустил простую ошибку в своем кодировании (отсюда два параграфа выше), и фактически код ниже теперь работает так, как я хочу.Это на паскале, но должно быть легко преобразовать его в C ++ или что-то еще.

program NoBorderProject;

uses
  Windows, Messages;
  {the Messages unit contains the windows
  Message constants like WM_COMMAND}

{$R *.RES}

var
  wClass: TWndClass;
  Msg: TMsg;
  win:HWND;
function WindowProc(hWnd,Msg,wParam,lParam:Integer):Integer; stdcall;
begin
 if Msg = WM_DESTROY then PostQuitMessage(0);
 Result := DefWindowProc(hWnd,Msg,wParam,lParam);
end;

begin
 wClass.lpszClassName:= 'CN';
 wClass.lpfnWndProc :=  @WindowProc;
 wClass.hInstance := hInstance;
 wClass.hbrBackground:= 1;
 RegisterClass(wClass);
 win := CreateWindow(wClass.lpszClassName,'Title Bar',
              WS_POPUP,//WS_OVERLAPPEDWINDOW or WS_VISIBLE,
              10,10,340,220,0,0,hInstance,nil);
 SetWindowLong(win, GWL_STYLE, WS_POPUP or WS_MINIMIZEBOX);
 SetWindowLong(win, GWL_EXSTYLE, 0 );
 ShowWindow(win,SW_SHOW);
 while GetMessage(Msg,0,0,0) do
   DispatchMessage(Msg);
end. 

Ответы [ 3 ]

13 голосов
/ 04 февраля 2011

Следующее выполняет работу:

hWnd = CreateWindow(...);
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP | WS_MINIMIZEBOX);
SetWindowLong(hWnd, GWL_EXSTYLE, 0);
ShowWindow(hWnd, ...);

Вы, вероятно, пропали без вести WS_MINIMIZEBOX.

4 голосов
/ 04 февраля 2011

Немного странно, но вы можете установить область окна, поместив это в событие YourForm.OnShow:

var
  r: TRect;
begin
  r := ClientRect;
  OffsetRect(r, 0, GetSystemMetrics(SM_CYCAPTION));
  OffsetRect(r, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
  SetWindowRgn(Handle, 
      CreateRectRgn(
          r.Left, r.Top, 
          ClientWidth + r.Left, ClientHeight + r.Top), True);
0 голосов
/ 05 февраля 2011

Вам необходимо переопределить TForm.CreateParams и установить или удалить любой стиль, который вас интересует

procedure TYourForm.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style and
  Params.ExStyle := Params.ExStyle or ;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...