• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

Possible Bug In VC19

Started by Frederick J. Harris, November 19, 2016, 05:09:19 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

James C. Fuller

José,
  This PbWin10 SDK code does not truncate the window on my Win10 64 machine.

'======================================================================
' Declares
'----------------------------------------------------------------------
#COMPILE EXE
'----------------------------------------------------------------------
#IF %PB_REVISION < &H1000 ' if compiler PBWIN9 or earlier
    %USEMACROS = 1
#ENDIF
#INCLUDE "WIN32API.INC"
'----------------------------------------------------------------------
%IDC_EDIT100       = 100


'======================================================================
FUNCTION WINMAIN (BYVAL hInst AS DWORD, BYVAL hPrevInstance AS DWORD, _
                  BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
'----------------------------------------------------------------------
' Program entrance
'----------------------------------------------------------------------
  LOCAL hDlg AS DWORD, hCtl AS DWORD, hFont AS DWORD, _
        sBuf AS STRING, wc AS WndClassEx, szClassName AS ASCIIZ * 80

  hFont = GetStockObject(%DEFAULT_GUI_FONT)

  szClassName      = "MyClassName"
  wc.cbSize        = SIZEOF(wc)
  wc.style         = %CS_HREDRAW OR %CS_VREDRAW
  wc.lpfnWndProc   = CODEPTR(WndProc)
  wc.cbClsExtra    = 0
  wc.cbWndExtra    = 0
  wc.hInstance     = hInst
  wc.hIcon         = LoadIcon  (%NULL, BYVAL %IDI_APPLICATION)
  wc.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)
  wc.hbrBackground = %COLOR_3DFACE + 1
  wc.lpszMenuName  = %NULL
  wc.lpszClassName = VARPTR(szClassName)
  wc.hIconSm       = LoadIcon  (%NULL, BYVAL %IDI_APPLICATION)
  CALL RegisterClassEx (wc)

  hDlg = CreateWindowEx(%WS_EX_DLGMODALFRAME OR %WS_EX_CONTROLPARENT OR %WS_EX_WINDOWEDGE, szClassName, "What is your name?", _
              %WS_POPUP OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %WS_CAPTION OR _
              %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT OR %DS_MODALFRAME OR _
              %DS_CENTER, _
              (GetSystemMetrics(%SM_CXSCREEN) - 246) / 2, _
              (GetSystemMetrics(%SM_CYSCREEN) - 110) / 2, _
               246, 110, 0, 0, GetModuleHandle(""), BYVAL %NULL)

  hCtl = CreateWindowEx(%WS_EX_CLIENTEDGE, "Edit", BYVAL %NULL, _
              %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_AUTOHSCROLL, _
               21, 20, 201, 19, _
               hDlg, %IDC_EDIT100, GetModuleHandle(""), BYVAL %NULL)
  IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

  hCtl = CreateWindowEx(0, "Button", "OK", _
              %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, _
               51, 52, 60, 23, _
               hDlg, %IDOK, GetModuleHandle(""), BYVAL %NULL)
  IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

  hCtl = CreateWindowEx(0, "Button", "Cancel", _
              %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, _
               126, 52, 60, 23, _
               hDlg, %IDCANCEL, GetModuleHandle(""), BYVAL %NULL)
  IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

  ShowWindow hDlg, nCmdShow
  UpdateWindow hDlg

  LOCAL Msg AS tagMsg
  WHILE GetMessage(Msg, %NULL, 0, 0)
      TranslateMessage Msg
      DispatchMessage Msg
  WEND

  FUNCTION = msg.wParam
END FUNCTION


'======================================================================
FUNCTION WndProc (BYVAL hWnd AS DWORD,  BYVAL wMsg AS DWORD, _
                  BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
'----------------------------------------------------------------------
' Main Window procedure
'----------------------------------------------------------------------
  SELECT CASE wMsg
  CASE %WM_CREATE
      'A good place to initiate things, declare variables,
      'create controls and read/set settings from a file, etc.
      '-------------------------------------------------------

  CASE %WM_COMMAND
      'Messages from controls and menu items are handled here.
      '-------------------------------------------------------
      SELECT CASE LOWRD(wParam)
      CASE %IDCANCEL  ' <- Esc key also triggers %IDCANCEL
          IF HIWRD(wParam) = %BN_CLICKED OR HIWRD(wParam) = 1 THEN
              SendMessage hWnd, %WM_DESTROY, wParam, lParam
              FUNCTION = 0 : EXIT FUNCTION
          END IF

      CASE %IDOK      ' <- Enter key usually triggers %IDOK
          IF HIWRD(wParam) = %BN_CLICKED OR HIWRD(wParam) = 1 THEN
              ' do whatever...
          END IF

      CASE %IDC_EDIT100
          SELECT CASE HIWRD(wParam)
          CASE %EN_UPDATE     ' Text is about to be changed
          CASE %EN_CHANGE     ' Text has changed
          CASE %EN_SETFOCUS   ' Control is getting focus
          CASE %EN_KILLFOCUS  ' Control is losing focus
          END SELECT

      END SELECT

  CASE %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT, %WM_CTLCOLORLISTBOX, %WM_CTLCOLORSTATIC
      ' wParam is handle of control's display context (hDC)
      ' lParam is handle of control
      ' Example on how to set colors to a specific control:
      '-----------------------------------------------------
      'IF lParam = GetDlgItem(hWnd, CtlId) THEN
      '   SetBkColor wParam, GetSysColor(%COLOR_INFOBK)
      '   SetTextColor wParam, GetSysColor(%COLOR_INFOTEXT)
      '   FUNCTION = GetSysColorBrush(%COLOR_INFOBK)
      '   EXIT FUNCTION
      'END IF
      '-----------------------------------------------------

  CASE %WM_DESTROY
      ' is sent when program ends - a good place to delete any created objects and
      ' store settings in file for next run, etc. Must send PostQuitMessage to end
      ' properly in SDK-style dialogs. The PostQuitMessage function sends a WM_QUIT
      ' message to the program's (thread's) message queue, and then WM_QUIT causes
      ' the GetMessage function to return zero in WINMAIN's message loop.
      '----------------------------------------------------------------------------
      PostQuitMessage 0
      FUNCTION = 0 : EXIT FUNCTION

  CASE %WM_SIZE
      IF wParam <> %SIZE_MINIMIZED THEN
          ' LOWRD(lParam) = width of dialog's client area
          ' HIWRD(lParam) = height of dialog's client area
          ' Example that resizes a control to dialog's client area:
          '------------------------------------------------------
          'SetWindowPos GetDlgItem(hWnd, CtlId), 0, 0, 0, _
          '             LOWRD(lParam), HIWRD(lParam), _
          '             %SWP_NOMOVE OR %SWP_NOZORDER
      END IF

  END SELECT

  FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION



No other compiler I have tried:
PbWin9
PbWin10
PbCC6
PbCC5
NUWEN GCC Distro
TDM-GCC Distro
PellesC 8
Tiny C 9.26
truncates the window except Visual Studio 2012 Express and Visual Studio 2015 Community.


James

Patrice Terrier

Scrollbars must be part of the client area (they are drawn directly by the OS itself) except with a Skin engine.

Also the scrollbars could be turned on or off, or only the vertical or the horizontal could be visible.
Or they can be enabled only after the window has been shown, based on what should be shown in it.

Think of a POPUP LISTBOX with the WS_EX_TOOLWINDOW StyleEx and any combination of WS_VSCROLL and/or WS_HSCROLL, like with my zTrace utility.

...


Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

José Roca

And what happens if you want that the visible content won't be reduced by the scrollbars? If you don't care, then call AdjustWindowRextEx directly.

James C. Fuller

Ok gentlemen you have convinced me:  "resistance is futile" :)
I tried adding WS_SCROLL | WS_HSCROLL to the style and of course it was as you said with all compilers.
I was worried my port of José's code would not work with the other compilers but all is well.
One item I feel should be in all c++ developers toolbox is the NUWEN distro:
https://nuwen.net/mingw.html
Take a check of his web site.

But the still unanswered question is when did the change take place with VS and where is it documented?

James

Patrice Terrier

For me the best window style is... WS_POPUP, without anything else, then you can take the control of your window just as you want.

Remember this old thread
http://www.jose.it-berater.org/smfforum/index.php?topic=1164.0

8)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Mike Lobanovsky

Quote from: Patrice Terrier on November 21, 2016, 12:11:36 PM
Scrollbars must be part of the client area (they are drawn directly by the OS itself) ...

Strictly speaking I'm afraid this isn't exactly so, Patrice.

Windows native scrollbars, disabled or enabled alike, that it adds in response to the WS_VSCROLL/WS_HSCROLL window styles, as opposed to their common or user control varieties, are not part of the window client area once they pop up automatically into view at app start or become visible through programmatic methods at some later point in time:

  • they do not respond to Windows hit test with a HTCLIENT flag but rather with HTVSCROLL and HTHSCROLL flags, respectively;
  • window client area as reported by the GetClientArea() API is reduced by the scrollbar sizes once they become visible; and
  • the user should utilize the GetWindowDC() accessor rather than GetDC() if they'd like to draw in the window area occupied by either scrollbar; in other words, any native scrollbar a window has is clipped out of its client area.
Contrary to that, the Common Controls' Flat Scroll Bar or custom user control scrollbars would be hosted in the window client area just like any other ordinary static or button or whatever controls and would not affect the window (non-)client area sizes, accessors or hit tests, and their underlying area would still be reported as HTCLIENT area. Of course, if you wouldn't fool the OS with your custom zzTop() hit testing in the meantime. :)
Mike
(3.6GHz Intel Core i5 w/ 16GB RAM, 2 x GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

#21
Here is how i check in WinLIFT (in polling mode)  if the scrollbars are visible or not.
(Using a combination of GetWindowRect and GetClientRect)

long skCheckScrollBar (IN HWND hWnd) {
//  Check if the control's scrollbars are shown.
//  Returns zero if (none, 1 if vertical, 2 if horizontal and 3 if both.
    RECT rw = {0}, rc = {0};
    long nRet = SCROLLBAR_NONE;
    if (IsWindowVisible(hWnd)) { // 06-25-2015
        GetWindowRect(hWnd, &rw);
        GetClientRect(hWnd, &rc);
        if (rc.right <= rw.right - rw.left - GetSystemMetrics(SM_CXVSCROLL)) { nRet = SCROLLBAR_VERT; }
        if (rc.bottom <= rw.bottom - rw.top - GetSystemMetrics(SM_CXHSCROLL)) { nRet = nRet + SCROLLBAR_HORZ; }
    }
    return nRet;
}


and for more oddities play with: menu, toolbar, statusbar, rebar and the like.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Frederick J. Harris

It looks like you've opened up a can of worms Jim! :)

Patrice Terrier

QuoteIt looks like you've opened up a can of worms Jim

And i have a couple more, when dealing with Windows 8+ 10, and moving unexpectedly a window outside of the bound edges of the desktop.

You must absolutly handle properly these messages:

    case %WM_GETMINMAXINFO
         pMM = lParam
         @pMM.ptMinTrackSize.x = gP.MinTrackSizeW
         @pMM.ptMinTrackSize.y = gP.MinTrackSizeH
         function = 0: exit function

    case %WM_MOVING '// Keep the window into the working area
         hMonitor = MonitorFromWindow(hWnd, %MONITOR_DEFAULTTONEAREST)
         lpr = lParam
         if (@lpr.nTop < 0) then @lpr.nTop = 0
         @lpr.nRight = @lpr.nLeft + gP.MinTrackSizeW
         @lpr.nBottom = @lpr.nTop + gP.MinTrackSizeH
         tmi.cbSize = sizeof(tmi)
         if (GetMonitorInfo(hMonitor, tmi)) then
             if (@lpr.nBottom > tmi.rcWork.nBottom) then
                 @lpr.nBottom = tmi.rcWork.nBottom
                 @lpr.nTop = @lpr.nBottom - gP.MinTrackSizeH
             end if
         end if
         function = %TRUE: exit function


Or Windows will resize your window based on its own rules despite of the minimum client size you specify, terrible when using a non-client area that doesn't use the Windows default theme.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Mike Lobanovsky

Quote from: Patrice Terrier on November 22, 2016, 10:06:06 AMmore oddities play with: menu, toolbar, statusbar, rebar and the like.

These, except for the menu that is a genuine non-client HTMENU area of the window, are all HTCLIENT area controls that don't affect the rectangle returned by a GetClientArea() call. In other words, they behave like ordinary labels, buttons, checkboxes, progressbars, etc. that you would put into the window client area to enable user interaction in accordance with your app's intended purposes. It's just another story that they are normally auto-resizable and would snap in their places all by themselves seamlessly unless given visible border styles of their own to discern them from the adjacent non-client spaces at a glance.

Quote from: Patrice Terrier on November 22, 2016, 03:57:01 PMAnd i have a couple more, when dealing with Windows 8+ 10 ...

You'd have a lot more than that had you tried to skin windows that belong to a process other than your own -- something such SW as e.g. Stardock Corp.'s WindowBlinds does. :)
Mike
(3.6GHz Intel Core i5 w/ 16GB RAM, 2 x GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

#25
Mike--

A skin engine is not intendend to skin the whole Windows UI, but only a specific window.
And you can use simultaneously different skins with specific applications.

On the other hand WindowBlinds is a Theme engine that substitutes its own graphic components in lieu of those being used by Windows, meaning ALL the windows have the same look (except those skinned).

Theming is {easier to program} than Skinning, because you just have to replace the default Windows theme components.
However there is much more graphic art work to do with theming to create all the bitmaps needed, including icons and a specific wallpapers background set. Doable only if you have a team of talented artist to concieve new themes.

Note: with Theming, all the GetSystemMetrics functions are matching those used by the theme.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Mike Lobanovsky

Quote from: Patrice Terrier on November 23, 2016, 11:56:00 AMA skin engine is not intendend to skin the whole Windows UI, but only a specific window.

Contemporary Eclecta (FBSL's official IDE application) is a very heavily skinned "specific window". Skinning (in your sense of the word) helps me keep the user environment consistent across the platforms and is also a tribute to XP that was the greatest OS I ever used.

Eclecta also happens to utilize a lot of owned child processes as its tools and utilities, and it would've been unnatural should all of them keep on using their own skins and colors, even if beautifully themed by a mature OS which of course can hardly be expected of such a graphical and metrical nuisance as Windows 10.

I guess Eclecta's skinning lies on the borderline between what you call themeing and skinning "a specific window" proper.

In fact the 64-bit Unicode child window chaos in Win 10's Calculator and Task Monitor was the only real reason why I would install Win 10 Pro Anniversary Edition at all. :)
Mike
(3.6GHz Intel Core i5 w/ 16GB RAM, 2 x GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

#27
Interresting threads about the same problem

http://stackoverflow.com/questions/11783086/get-exact-window-region-size-createwindow-window-size-isnt-correct-size-of-wi

http://stackoverflow.com/questions/27928254/adjustwindowrectex-and-getwindowrect-give-wrong-size-with-ws-overlapped

When in aero mode, see also the DwmGetWindowAttribute function

Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing.
The borders might look like this: 7,0,7,7 (left, top, right, bottom)

http://stackoverflow.com/questions/34139450/getwindowrect-returns-a-size-including-invisible-borders
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

Rather than GetWindowRect, use this API to retrieve the correct size in DWM AERO mode

RECT lpr = { 0 };
HRESULT hRes =  DwmGetWindowAttribute(hWin, DWMWA_EXTENDED_FRAME_BOUNDS, &lpr, sizeof(RECT));


And to detect if DWM is enabled, here is what i am doing in WinLIFT

long zDwmIsCompositionEnabled () {
    long nRet = 0;
    HMODULE hLib = LoadDWM();
    if (hLib) {
        long_proc (BOOL*);
        zProc hProc = (zProc) GetProcAddress(hLib, "DwmIsCompositionEnabled");
        if (hProc) {
            BOOL bAero = FALSE;
            if (hProc(&bAero) == 0) {
                if (bAero) { nRet = -1; }
            }
        }
    }
    return nRet;
}


Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Mike Lobanovsky

Quote from: Patrice Terrier on November 24, 2016, 09:56:47 AMWindows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing.
The borders might look like this: 7,0,7,7 (left, top, right, bottom)

http://stackoverflow.com/questions/34139450/getwindowrect-returns-a-size-including-invisible-borders

Hehe, thanks for this link Patrice!

It actually points to an answer (at the very bottom of the page) that contains yet another link:

http://winaero.com/blog/enable-the-hidden-aero-lite-theme-in-windows-10/

which teaches us how to non-intrusively enable Windows 10 unofficial Aero Lite theme that would make those invisible border extras fully visible and that would also bring the GetWindowRect() returns back to their expected visually consistent values! :)

For all intents and purposes, Aero Lite is roughly equivalent to Basic-style non-Aero theming in Vista and 7.

Addendum to the above link:

Once you double-click the new AeroLite.theme file on your desktop to install the new Basic-like theme in your system, you may safely delete this file from your desktop altogether. The new theme will be installed permanently alongside the other themes available via standard Personalization->Theming functionality.
Mike
(3.6GHz Intel Core i5 w/ 16GB RAM, 2 x GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)