JonRobertson 72 Posted August 5 I have very little experience with changing UI at the Windows message level. I am hoping someone can explain a behavior that is confusing to me. The purpose of my question is strictly educational. In the attached demo project, WM_NCCALCSIZE attempts to change the form's client area to the entire form, without the caption bar. Decreasing NCCalcSizeParams.rgrc[0].Top by 31 (scaled if needed) does what I expect: Using a value of 30 gives me this: In the second example, Windows does not recognize the caption bar as part of the window. For example, clicking in that area sends the mouse click message to the window under my form. That makes sense to me. What I don't understand is why changing the value that I decrease from .Top from 30 to 31 makes such a difference in whether the painted client area "includes" the caption bar, for lack of a better description. I would expect values between 1 and 30 to gradually hide (?) the caption bar, rather than all or nothing. I also have not figured out how to determine that 31 is the value needed to accomplish the first image. I've tried various system metrics values such as SM_CYCAPTION, SM_CYFIXEDFRAME, and SM_CYDLGFRAME. Even combining SM_CYCAPTION with one of the SM_CY*FRAME values results in a value that is too small. My current interest is in a non-themed or Windows themed application. I have looked at TFormStyleHook.WMNCCalcSize to see how the VCL handles WM_NCCalcSize when themed. But that didn't help me understand the behavior that I'm seeing without themes. Thanks WMNCCalcSize.zip Share this post Link to post
Kas Ob. 121 Posted August 5 Have you tried WM_GETTITLEBARINFOEX ? Its message structure not available in XE8, so i can't try it, but seeing this : https://stackoverflow.com/questions/60667679/delphi-overlap-window-form-titlebar then TTitleBarInfoEx should be available in newer versions. Share this post Link to post
JonRobertson 72 Posted August 5 13 minutes ago, Kas Ob. said: Have you tried WM_GETTITLEBARINFOEX No, I didn't know about that Windows message. So I learned something today. The rcTitleBar.height coming back from WM_GETTITLEBARINFOEX is 23, which is the same value that I get from GetSystemMetrics(SM_CYCAPTION). Unfortunately that is not high enough to get the behavior that I'm expecting. Oddly (to me), the height for the various min/max/close buttons comes back as 24. Share this post Link to post
Kas Ob. 121 Posted August 5 Searching the Internet kept landing me on the same approach, using "Self.Height - ClientHeight" the result was 39 pixel, and using print screen and painter to find the title bar height kept giving me 29 pixel, so some subtraction will be needed from the first, which i think it borders.... Anyway i found this https://stackoverflow.com/questions/28524463/how-to-get-the-default-caption-bar-height-of-a-window-in-windows Which is does return 31 pixel, so it might be your solution, or at least it a lead to a solution. Please share your finding with us. Share this post Link to post
JonRobertson 72 Posted August 5 15 minutes ago, Kas Ob. said: Anyway i found this https://stackoverflow.com/questions/28524463/how-to-get-the-default-caption-bar-height-of-a-window-in-windows Nice. I spent several hours searching for answers over the weekend and did not come across that calculation. I completely overlooked SM_CXPADDEDBORDER. That answers the question of how to determine the value to use. This works for me: procedure TfrmMain.WMNCCalcSize(var Message: TWMNCCalcSize); begin inherited; var captionHeight := GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXPADDEDBORDER); var Scale := RoundTo(CurrentPPI / Screen.DefaultPixelsPerInch, -2); var NCCalcSizeParams := Message.CalcSize_Params; Dec(NCCalcSizeParams.rgrc[0].Top, Round(captionHeight * Scale)); end; Does anyone know why using a value of one less than captionHeight results in the entire caption bar being painted? Thanks again. Share this post Link to post
dwrbudr 8 Posted August 5 You could try DwmGetWindowAttribute along with DWMWA_CAPTION_BUTTON_BOUNDS to get the title bar height Share this post Link to post
Kas Ob. 121 Posted August 6 13 hours ago, JonRobertson said: Does anyone know why using a value of one less than captionHeight results in the entire caption bar being painted? I still thinking about this, and as no one added any input then i add my assumption. I think the logic behind this is very simple, Windows has its default drawing (themed or not) and if you are changing its parameters in whole or in some then you are on your own. In examples might be easier to explain, like, while you change the height of an item in ListBox or ListView, then the default drawing/rendering for item will perform according to its default no matter what you have set, if you set the item height to 3 pixel then you will see the item drawn by OS stayed as default like 8 pixel and the items will overlap, same if you set them to something like 50 pixel, the system will not check and adjust the font size neither the image or checkboxes... Its like an unspoken rule, if you are changing the height then you have to continue and override the default drawing, and draw your own title/item.. with your own drawing function and your own font, brush, pen.... Share this post Link to post
Kas Ob. 121 Posted August 6 One more thing that bothering me, and you might test and confirm as you or somebody have some insight on this: Do the borders scale ? I mean the border is there for reason and they are one pixel wide, for the window title, but when scaled to 200% do they become 2 pixel ? or they stayed as 1pixel? See, windows shadow bothered me in the past and they changed few times over many Windows versions, their scaling too. Share this post Link to post