Może nawet tak być, w co i tak wątpię, ponieważ API było robione i doskonalone przez 20 lat z górką, więc tam aż takich bagów raczej nie powinno być!
Ale gdy faktycznie jest tak jak mówisz, to i tak nie powinno to wpływać na działanie aplikacji!
Bowiem, w systemach typu GUI, Ty zawsze masz obowiązek przerysować swoje okno - na żądanie systemu!
Mało: masz to robić w dowolnej żądanej rozdzielczości, bo user może zmienić rozdzielczość ekranu w dowolnej chwili,
albo chce to wydrukować - przesłać na drukarkę, która ma zwykle z 10 razy większą rozdzielczość od monitora!
Ale czemu nazywasz to "bagiem"? Może tak właśnie miało być?
Jak nie wierzysz, napisz sobie na szybko obsługę WM_NCPAINT i odczytaj wParm, w którym zakodowany jest region (HRGN). Wtedy zobaczysz, że przesyłany jest tam rozmiar okna jeszcze przed zmianą formy, a nie już zaktualizowany. Testowałem to na czystej apce, bez obsługi jakichkolwiek komunikatów poza właśnie WM_NCPAINT, także wykluczam moją winę.
A tak w ogóle, to z tym już sobie poradziłem. Wrzuciłem do klasy zmienną, która po prostu zapisuje wymiary okna zaraz po WM_NCCALCSIZE (następującym na długo przed WM_SIZE) i potem WM_NCPAINT - gdy przyjdzie jego kolej - sobie z tego korzysta, zamiast z kulawego wParm.
Problem mam taki, że chcę odgórnie wymusić na formie BorderStyle = bsNone, jeszcze zanim apka zacznie wykonywać jakiekolwiek kalkulacje związane z formą. Próbowałem to zrobić w konstruktorze, w ReadState, w CreateParms, ale to ciągle zbyt późno. Po prostu źle mi przelicza rozmiar klienta, bo już wcześniej dokonuje przeliczeń w oparciu o BorderStyle pobrane z inspektora. I tak np. w inspektorze ClientWidth wynosi 1200, a po skompilowaniu zmienia się w 1186. Nie byłoby problemem wyrównać to ręcznie, gdyby nie fakt, że rozmiar klienta zmienia się w zależności o wartości BorderStyle w inspektorze. Inny pojawia się dla bsNone, inny dla bsSingle, inny dla bsSizeable... I to pomimo faktu, że w konstruktorze narzucam mu bsNone, który po odpaleniu aplikacji faktycznie zostaje wykonany (próbowałem na różne sposoby, także przez SetWindowLong i zmianę WindowStyle). tylko co z tego, skoro rozmiar klienta jest już wtedy skopany.
Wydaje mi się więc, że albo muszę odnaleźć pierwotny komunikat, który za to odpowiada, albo po prostu zmienić property BorderStyle jeszcze zanim apka cokolwiek przeliczy. Z tym ClassHelperem to była niezła sugestia, tylko mój kompilator (Delphi 7), tego nie ma :).
Ja tak to sprawdzam:
procedure TForm1.NonClientPaint(var MSG: TWMNCPAINT);
var
Rec: TRect;
begin
inherited;
GetRgnBox(MSG.RGN, Rec);
ShowMessage('Width ' + IntToStr(Rec.Right - Rec.Left));
ShowMessage('Height ' + IntToStr(Rec.Bottom - Rec.Top));
end;
Potem w Buttonie ustawiam sobie coś takiego:
Width:= 700
Okienko i tak wypluwa mi pierwotne Width = 1200.