Jeżeli tworzymy aplikację MDI i przesuniemy okno – dziecko poza obszar roboczy rodzica, to pojawią się w owym rodzicu ScrollBary, niechciane niekiedy. Natknąłem się na ten problem i znalazłem tylko jedno gotowe rozwiązanie, które na dodatek było niechlujnie (wg mnie) napisane, a poza tym nie zawierało żadnego opisu, dlatego zamieszczam kod wraz z moimi komentarzami.
OnCreate głównej formy powinno wyglądać tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
procedure TmainForm.FormCreate(Sender: TObject); begin // w drugim ifie sprawdzamy, czy miejsce przeznaczone do użycia przez nas jest wolne (wtedy zwrócone będzie 0) // następnie ustawiamy w tym miejscu wartość zwróconę przez zagnieżdzoną funkcję SetWindowLong - ustawiamy w niej adres // naszej funkcji obsługi okna, a funkcja ta (SetWindowLong) jako wartość zwracaną podstawia (w tym przypadku) adres poprzedniej funkcji okienkowej if ClientHandle <> 0 then if (GetWindowLong(ClientHandle, GWL_USERDATA) = 0) then SetWindowLong(ClientHandle, GWL_USERDATA, SetWindowLong(ClientHandle, GWL_WNDPROC, Integer(@ClientWindowProc))); end; |
Teraz, przed OnCreate głównej formy dodajemy tą funkcję:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
function ClientWindowProc(Wnd: HWND; Msg: Cardinal; WParam, LParam: Integer) : Integer; stdcall; var f: Pointer; begin // pobieramy spod GWL_USERDATA adres poprzedniej, domyślnej funkcji obsługi okna // potem, jeżeli ScrollBary są ustawione, to zmieniamy styl okna na taki jaki // właśnie obowiązuje z wyłączeniem ScrollBarów f := Pointer(GetWindowLong(Wnd, GWL_USERDATA)); if Msg = WM_NCCALCSIZE then if (GetWindowLong(Wnd, GWL_STYLE) and (WS_HSCROLL or WS_VSCROLL)) <> 0 then SetWindowLong(Wnd, GWL_STYLE, GetWindowLong(Wnd, GWL_STYLE) and not (WS_HSCROLL or WS_VSCROLL)); // wywołujemy główną funkcję okienkową Result := CallWindowProc(f, Wnd, Msg, WParam, LParam); end; |
Autor: Iskar