11-29-2022, 11:46 PM
Hey if you like borderless windows but want a way to resize them forget about using $RESIZE. It has no border to grab on to. Oh, if you don't mind ugly, or want an all black window, you can add a WS_THICKBORDER element to your API call, which Steve discovered, but it's ugly. (It leaves a thin black row just below the top white border in any window that has a colored background.) Anyway, if you don't mind that, you can use it with QB64 $RESIZE. If you want an alternative to $RESIZE, try something like this...
Try a mouse drag at any side or any corner to enlarge or shrink the borderless window. Esc to quit.
Something I may try later is using the _NEWIMAGE equivalent of SCREEN 0. I'd like to see if that would eliminate the need to load QB64 default 16 size font. One problem with window sizing in SCREEN 0 is that 16 size font gets traded out at different sizes with what I think is the 8 size square font. Anyway, that causes irregular resizing results. Specifying _FONT 16 prevents that occurrence.
As always, if anyone has any improvement suggestions, go ahead and post them. A nice perk to sharing code is more minds often results in more performance.
Pete
Try a mouse drag at any side or any corner to enlarge or shrink the borderless window. Esc to quit.
Code: (Select All)
DIM SHARED WinMse AS POINTAPI
TYPE POINTAPI
X_Pos AS LONG
Y_Pos AS LONG
END TYPE
DECLARE DYNAMIC LIBRARY "user32"
FUNCTION ShowWindow& (BYVAL hwnd AS LONG, BYVAL nCmdShow AS LONG)
FUNCTION GetAsyncKeyState% (BYVAL vkey AS LONG)
FUNCTION GetCursorPos (lpPoint AS POINTAPI)
FUNCTION FindWindowA& (BYVAL ClassName AS _OFFSET, WindowName$) 'handle by title
REM FUNCTION ShowWindow& (BYVAL hwnd AS LONG, BYVAL nCmdShow AS LONG) 'maximize process
FUNCTION GetForegroundWindow& 'Find currently focused process handle
FUNCTION SetWindowPos& (BYVAL hWnd AS LONG, BYVAL hWndInsertAfter AS _OFFSET, BYVAL X AS INTEGER, BYVAL Y AS INTEGER, BYVAL cx AS INTEGER, BYVAL cy AS INTEGER, BYVAL uFlags AS _OFFSET)
FUNCTION GetWindowLongA& (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG)
FUNCTION SetWindowLongA& (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG, BYVAL dwNewLong AS LONG)
FUNCTION SetLayeredWindowAttributes& (BYVAL hwnd AS LONG, BYVAL crKey AS LONG, BYVAL bAlpha AS _UNSIGNED _BYTE, BYVAL dwFlags AS LONG)
FUNCTION SetCursorPos% (BYVAL cx AS INTEGER, BYVAL cy AS INTEGER)
SUB SENDKEYS ALIAS keybd_event (BYVAL bVk AS LONG, BYVAL bScan AS LONG, BYVAL dwFlags AS LONG, BYVAL dwExtraInfo AS LONG)
END DECLARE
DIM AS INTEGER setcurx, setcury, sizeit, oldmx, oldmy, x, y, fw, fh
x = _SCREENX
y = _SCREENY
w = _WIDTH
h = _HEIGHT
fw = _FONTWIDTH
fh = _FONTHEIGHT
DIM hWnd AS LONG
hWnd = _WINDOWHANDLE
_DELAY .1
GWL_STYLE = -16
WS_POPUP = &H4800000 ' Can be used to make a razor thin border but is not resizable.
ws_border = &H800000
WS_VISIBLE = &H10000000
DO
winstyle& = GetWindowLongA&(hWnd, GWL_STYLE)
LOOP UNTIL winstyle&
DO
a& = SetWindowLongA&(hWnd, GWL_STYLE, winstyle& AND WS_VISIBLE)
LOOP UNTIL a&
a& = SetWindowPos&(hWnd&, 0, 0, 0, 0, 0, 39) ' Required to allow printing where title bar used to be.
_DELAY .1
wintp = _SCREENY \ fh: winbt = _SCREENY \ fh + _HEIGHT: winlt = _SCREENX \ fw: winrt = _SCREENX \ fw + _WIDTH
DO
_LIMIT 60
WHILE _MOUSEINPUT: WEND
IF _MOUSEBUTTON(1) THEN lb = 1 ELSE IF lb = 1 AND _MOUSEBUTTON(1) = 0 THEN lb = 0: side$ = "": enl = 0
z& = GetCursorPos(WinMse)
setcurx = WinMse.X_Pos: setcury = WinMse.Y_Pos
WinMse.X_Pos = WinMse.X_Pos \ fw
WinMse.Y_Pos = WinMse.Y_Pos \ fh
IF lb THEN
IF LEN(side$) THEN
IF oldmx <> WinMse.X_Pos OR oldmy <> WinMse.Y_Pos THEN
DO ' Falx loop.
SELECT CASE side$
CASE "left-top"
sizeit = -SGN(oldmy - WinMse.Y_Pos) * ABS(oldmy - WinMse.Y_Pos)
IF sizeit THEN GOSUB topsize
sizeit = SGN(oldmx - WinMse.X_Pos) * ABS(oldmx - WinMse.X_Pos)
IF sizeit THEN GOSUB leftsize
CASE "right-top"
sizeit = -SGN(oldmy - WinMse.Y_Pos) * ABS(oldmy - WinMse.Y_Pos)
IF sizeit THEN GOSUB topsize
sizeit = -SGN(oldmx - WinMse.X_Pos) * ABS(oldmx - WinMse.X_Pos)
IF sizeit THEN GOSUB rightsize
CASE "left-bottom"
sizeit = SGN(oldmx - WinMse.X_Pos) * ABS(oldmx - WinMse.X_Pos)
IF sizeit THEN GOSUB leftsize
sizeit = SGN(oldmy - WinMse.Y_Pos) * ABS(oldmy - WinMse.Y_Pos)
IF sizeit THEN GOSUB bottomsize
CASE "right-bottom"
sizeit = -SGN(oldmx - WinMse.X_Pos) * ABS(oldmx - WinMse.X_Pos)
IF sizeit THEN GOSUB rightsize
sizeit = SGN(oldmy - WinMse.Y_Pos) * ABS(oldmy - WinMse.Y_Pos)
IF sizeit THEN GOSUB bottomsize
CASE "top" ' up/down
sizeit = -SGN(oldmy - WinMse.Y_Pos) * ABS(oldmy - WinMse.Y_Pos)
IF sizeit THEN GOSUB topsize
CASE "bottom"
sizeit = SGN(oldmy - WinMse.Y_Pos) * ABS(oldmy - WinMse.Y_Pos)
IF sizeit THEN GOSUB bottomsize
CASE "left"
sizeit = SGN(oldmx - WinMse.X_Pos) * ABS(oldmx - WinMse.X_Pos)
IF sizeit THEN GOSUB leftsize
CASE "right"
sizeit = -SGN(oldmx - WinMse.X_Pos) * ABS(oldmx - WinMse.X_Pos)
IF sizeit THEN GOSUB rightsize
END SELECT
wintp = y \ fh: winbt = y \ fh + _HEIGHT: winlt = x \ fw: winrt = x \ fw + _WIDTH
EXIT DO
LOOP
END IF
END IF
ELSE
IF WinMse.X_Pos = winlt AND WinMse.Y_Pos = wintp THEN
_MOUSESHOW "TOPLEFT_BOTTOMRIGHT": side$ = "left-top"
ELSEIF WinMse.X_Pos = winlt AND WinMse.Y_Pos = winbt THEN _MOUSESHOW "TOPRIGHT_BOTTOMLEFT": side$ = "left-bottom"
ELSEIF WinMse.X_Pos = winrt AND WinMse.Y_Pos = wintp THEN _MOUSESHOW "TOPRIGHT_BOTTOMLEFT": side$ = "right-top"
ELSEIF WinMse.X_Pos = winrt AND WinMse.Y_Pos = winbt THEN _MOUSESHOW "TOPleft_BOTTOMRIGHT": side$ = "right-bottom"
ELSEIF WinMse.X_Pos = winlt THEN _MOUSESHOW "HORIZONTAL": side$ = "left"
ELSEIF WinMse.X_Pos = winrt THEN _MOUSESHOW "HORIZONTAL": side$ = "right"
ELSEIF WinMse.Y_Pos = wintp THEN _MOUSESHOW "VERTICAL": side$ = "top"
ELSEIF WinMse.Y_Pos = winbt THEN _MOUSESHOW "VERTICAL": side$ = "bottom"
ELSE
IF LEN(side$) THEN side$ = "": _MOUSESHOW "default"
END IF
END IF
oldmx = WinMse.X_Pos: oldmy = WinMse.Y_Pos
IF INKEY$ = CHR$(27) THEN SYSTEM
LOOP
topsize:
IF h - sizeit < 5 THEN RETURN
h = h - sizeit
x = _SCREENX
y = _SCREENY + sizeit * fh
WIDTH w, h
_FONT 16
_SCREENMOVE x, y
z% = SetCursorPos%(setcurx, setcury)
RETURN
leftsize:
IF w + sizeit < 15 THEN RETURN
w = w + sizeit
x = _SCREENX - sizeit * fw
y = _SCREENY
WIDTH w, h
_FONT 16
_SCREENMOVE x, y
z% = SetCursorPos%(x, setcury)
RETURN
rightsize:
IF w + sizeit < 15 THEN RETURN
w = w + sizeit
x = _SCREENX - sizeit * fw
y = _SCREENY
WIDTH w, h
_FONT 16
x = _SCREENX: y = _SCREENY
z% = SetCursorPos%(x + _WIDTH * fw, setcury)
RETURN
bottomsize:
IF h - sizeit < 5 THEN RETURN
h = h - sizeit
WIDTH w, h
_FONT 16
x = _SCREENX: y = _SCREENY
z% = SetCursorPos%(setcurx, y + _HEIGHT * fh)
RETURN
Something I may try later is using the _NEWIMAGE equivalent of SCREEN 0. I'd like to see if that would eliminate the need to load QB64 default 16 size font. One problem with window sizing in SCREEN 0 is that 16 size font gets traded out at different sizes with what I think is the 8 size square font. Anyway, that causes irregular resizing results. Specifying _FONT 16 prevents that occurrence.
As always, if anyone has any improvement suggestions, go ahead and post them. A nice perk to sharing code is more minds often results in more performance.
Pete