Author Topic: Patch to SLEEP, _KEYHIT, INP(&H60), _SCREENEXISTS and more...  (Read 341 times)

SMcNeill

  • Moderator
  • Hero Member
  • *****
  • Posts: 6226
Patch to SLEEP, _KEYHIT, INP(&H60), _SCREENEXISTS and more...
« on: September 23, 2017, 05:52:12 pm »
Just pushed a patch into the repo which corrects several of the little issues which were bugging me on Windows.

First, it corrects the issue with SLEEP, _KEYHIT, and INP(&H60) responding to modifier keypresses when the window isn't in focus.  SHIFT, CTRL,  and ALT should no longer affect our program unless it's the focus of our screen.  (Tab out of a program, it shouldn't break sleep when you hit shift or the other modifier keys anymore, until you tab back to it.)

Also pushed a change to _SCREENEXISTS so that it now requires not only that glut has finished initializing a screen, but that Windows has also registered a handle for that screen, before returning a -1 value for us.  This makes it *actually* useful, as before it was telling us information which really didn't serve any real use for us.  It doesn't matter if glut has created the window, if windows hasn't registered a handle for it already!

An example of _SCREENEXISTS now being actually useful:
Code: [Select]
DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION GetForegroundWindow%& ()
    FUNCTION FindWindowA%& (BYVAL lpClassName%&, BYVAL lpWindowName%&)
END DECLARE


DO
    _LIMIT 100
    PRINT _SCREENEXISTS
LOOP UNTIL _SCREENEXISTS

DIM title AS STRING
DIM hWnd AS _OFFSET

title = "Whatever you actually want the title to be"
_TITLE title
title = title + CHR$(0) 'always add character zero to FindWindowA string parameter
hWnd = FindWindowA(0, _OFFSET(title))

DO UNTIL LEN(INKEY$)
    IF hWnd = GetForegroundWindow THEN PRINT "foreground" ELSE PRINT "not foreground"
    SLEEP 1
LOOP
END

Versions of QB64 prior to this patch would generate an error with the call to FindWindowA as it was being called before windows had assigned a handle to our program.  Now, it'll wait like it's supposed to, for Windows to return us a valid handle for the window before doing anything else.  ;D

NOTE:  All these changes are for Window users ONLY.  As far as I know, Linux and Max didn't have these issues to begin with, and waiting for Linux to return you a handle to a Windows process isn't something that would ever work...

Also patched some of the other screen commands for windows so that they'll be less likely to fail if called early in a program.  _SCREENHIDE, _DESKTOPWIDTH, _DESKTOPHEIGHT, sub _SCREENICON and function _SCREENICON were all modified to make certain that they wait for windows to have a proper window handle for our program before they try to execute and do nothing if it doesn't exist yet. 


NOTE2: Changes should go live in tomorrow's dirty build, or else you can download and build fresh from the repo any time you want, manually.
http://bit.ly/Color32BI -- A set of color CONST for use in 32 bit mode, as a BI library.

SMcNeill

  • Moderator
  • Hero Member
  • *****
  • Posts: 6226
Re: Patch to SLEEP, _KEYHIT, INP(&H60), _SCREENEXISTS and more...
« Reply #1 on: September 23, 2017, 10:12:23 pm »
Another change pushed to the repo -- _SCREENCLICK now accepts a third parameter in Windows.

_SCREENCLICK x, y, button

x, y is the position of the screen where you want to create a mouseclick
button is an optional parameter which allows you to specify which mousebutton you want to click:
1 = left
2 = right
3 = middle

So a _SCREENCLICK 100, 100, 1  would do a left mouseclick at 100,100 on your desktop, and _SCREENCLICK 100, 100, 2 would do a right mouseclick at that position.
http://bit.ly/Color32BI -- A set of color CONST for use in 32 bit mode, as a BI library.

RhoSigma

  • Sr. Member
  • ****
  • Posts: 352
  • Out of Time !!
Re: Patch to SLEEP, _KEYHIT, INP(&H60), _SCREENEXISTS and more...
« Reply #2 on: September 24, 2017, 09:28:16 am »
Hi Steve,

just tested your patches (build 20170924.68) hoping that it will fix some SCREEN issues I have, but unfortunately it does not.

See ScreenTest.bas
Code: [Select]
'avoid SCREEN 0 popup (NOTE: QB64-GL obviously doesn't like this Metacommand)
$SCREENHIDE

'create new screen, center it, then open (show) it
'QB64-SDL: window opens centered on desktop without flickering or jumping
'          around, just as intended by this code snippet
'
' QB64-GL: - no window opens, program will hang, use TaskManager to kill
'          - for workaround you must delete the $SCREENHIDE above, but then
'            SCREEN 0 is opening first (in any place), then it changes to the
'            the newly created SCREEN, then it will be centered, which causes
'            flickering and windows jumping around on the desktop, which looks
'            very unprofessional and does annoy other people working with your
'            programs
'          - this is the #1 reason, why I still stick to the old SDL version
SCREEN _NEWIMAGE(640, 480, 256)
_SCREENMOVE _MIDDLE
_SCREENSHOW

PRINT "press any key to quit..."
SLEEP
SYSTEM

I'd consider this a high priority issue, which needs to be fixed to make QB64 programs behaving more reliable/professional. Would be nice, if you or anyone else who's familiar with QB64's internals, could sort this out in the future.

Thank you

FellippeHeitor

  • QB64 Partner Site Owner
  • Hero Member
  • *
  • Posts: 1770
  • LET IT = BE
    • QB64.org
Re: Patch to SLEEP, _KEYHIT, INP(&H60), _SCREENEXISTS and more...
« Reply #3 on: September 24, 2017, 09:59:54 am »
Why don't you use _SCREENHIDE instead of $SCREENHIDE? The result is almost identical to what you get in pre-1.000 versions.

Besides,

needs to be fixed to make QB64 programs behaving more reliable/professional.

Professional programs hardly ever center their windows. They just come up where the OS throws them initially, or, at most, remember where they were before.

Would be nice, if you or anyone else who's familiar with QB64's internals, could sort this out in the future.

I wouldn't say I'm not familiar with the internals, but given the way the affected code has been rewritten by Galleon in the transition from using SDL to using OpenGL, it doesn't look like it'll ever behave the same unless there was to be another switch of libraries.

Pre-1.000:
Code: [Select]
if (screen_hide) return;

1.000-forward:
Code: [Select]
    if (!screen_hide) create_window=1;
   
    while (!create_window){Sleep(100);}
« Last Edit: September 24, 2017, 10:09:27 am by FellippeHeitor »

SMcNeill

  • Moderator
  • Hero Member
  • *****
  • Posts: 6226
Re: Patch to SLEEP, _KEYHIT, INP(&H60), _SCREENEXISTS and more...
« Reply #4 on: September 24, 2017, 11:35:10 am »
I see this a few lines down:      //glutInitWindowPosition(300, 200);

Leads me to wonder if there might be a simple way to use a metacommand to set that (300,200) for us before compiletime.

$SCREENSET:100, 100
$SCREENSET:MIDDLE

Have it pass a variable with that information and set a flag for if (screenset) {glutInitWindowPosition(InitialX, InitialY);}

Could bypass the whole need to $SCREENHIDE, _SCREENMOVE, $SCREENSHOW for us...
http://bit.ly/Color32BI -- A set of color CONST for use in 32 bit mode, as a BI library.

RhoSigma

  • Sr. Member
  • ****
  • Posts: 352
  • Out of Time !!
Re: Patch to SLEEP, _KEYHIT, INP(&H60), _SCREENEXISTS and more...
« Reply #5 on: September 24, 2017, 11:45:23 am »
Why don't you use _SCREENHIDE instead of $SCREENHIDE? The result is almost identical to what you get in pre-1.000 versions.

I already tried that too, but the keyword here is almost, for me here on my Laptop, i still see the SCREEN 0 before my newly created one, even on my CAD/CAM Workstation at work, which is approx. 2.5 times as fast as my Laptop, I still can see there is something poppin' up before my created SCREEN image.
As to my understanding, with _SCREENHIDE i can hide the open program window, but with $SCREENHIDE i do avoid the program window is created at all until I use _SCREENSHOW.

Professional programs hardly ever center their windows. They just come up where the OS throws them initially, or, at most, remember where they were before.

Well, you missed the point here, the unprofessional behaviour i talk about is the defintely visible flickering caused by the fact that the program window will popup, then resize to my specified resolution and finally jumps to its final destination, doesn't matter if this is centered, left or right justified or even an earlier saved position.

I wouldn't say I'm not familiar with the internals, but given the way the affected code has been rewritten by Galleon in the transition from using SDL to using OpenGL, it doesn't look like it'll ever behave the same unless there was to be another switch of libraries.

That's what I'm afraid of, so I'll probably stick to SDL forever, at least where other people use my programs...

I see this a few lines down:      //glutInitWindowPosition(300, 200);

Leads me to wonder if there might be a simple way to use a metacommand to set that (300,200) for us before compiletime.

$SCREENSET:100, 100
$SCREENSET:MIDDLE

Have it pass a variable with that information and set a flag for if (screenset) {glutInitWindowPosition(InitialX, InitialY);}

Could bypass the whole need to $SCREENHIDE, _SCREENMOVE, $SCREENSHOW for us...

This would be an optimal solution, but for completeness it should also specify the color depth. This way we could hardcode our desired screenimage, its position and size, instead of always starting our programs off at SCREEN 0.