Author Topic: _SCREENPRINT text$ Question  (Read 4793 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #15 on: October 05, 2021, 02:14:36 am »
QB64 has a some very good mouse handling capabilities. I usually like to mix y inkey and mouse routines together, something like this bare bones example.

Code: QB64: [Select]
  1. mydemo% = -1
  2.     _LIMIT 30
  3.     b$ = INKEY$
  4.     IF LEN(b$) THEN
  5.         SELECT CASE LEN(b$)
  6.             CASE 1
  7.                 SELECT CASE b$
  8.                     CASE CHR$(27): EXIT DO
  9.                     CASE ELSE
  10.                         IF mydemo% THEN mydemo% = 1: CALL mroutine(drag, double_click_lt, mydemo%)
  11.                 END SELECT
  12.             CASE 2
  13.                 SELECT CASE RIGHT$(b$, 1)
  14.                     CASE ELSE
  15.                         IF mydemo% THEN mydemo% = 2: CALL mroutine(drag, double_click_lt, mydemo%)
  16.                 END SELECT
  17.         END SELECT
  18.     ELSE
  19.         CALL mroutine(drag, double_click_lt, mydemo%)
  20.     END IF
  21.  
  22. SUB mroutine (drag, double_click_lt, mydemo%)
  23.     STATIC z1, lclick, bactive, oldmx, oldmy
  24.  
  25.     IF mydemo% > 0 THEN GOSUB mydemo: EXIT SUB
  26.  
  27.     IF lclick THEN
  28.         IF TIMER < z1 THEN z1 = z1 - 86400 ' Midnight adjustment.
  29.         IF TIMER - z1 > .33 THEN lclick = 0
  30.     END IF
  31.  
  32.         mw = mw + _MOUSEWHEEL
  33.     WEND
  34.  
  35.     mx = _MOUSEX
  36.     my = _MOUSEY
  37.     lb = _MOUSEBUTTON(1)
  38.     rb = _MOUSEBUTTON(2)
  39.     mb = _MOUSEBUTTON(3)
  40.  
  41.     IF bactive THEN
  42.         SELECT CASE bactive
  43.             CASE -1
  44.                 IF lb = 0 THEN
  45.                     SELECT CASE lclick
  46.                         CASE 0
  47.                             IF mydemo% THEN mydemo% = 3: GOSUB mydemo
  48.                             lclick = lclick + 1
  49.                         CASE ELSE ' Double click. Completed upon 2nd left button release.
  50.                             IF mydemo% THEN mydemo% = 11: GOSUB mydemo
  51.                             double_click_lt = -1
  52.                             lclick = 0
  53.                     END SELECT
  54.                     bactive = 0
  55.                     IF drag THEN drag = 0
  56.                 ELSE
  57.                     IF mx <> oldmx OR my <> oldmy THEN
  58.                         IF mydemo% THEN mydemo% = 12: GOSUB mydemo
  59.                         drag = -1
  60.                     END IF
  61.                 END IF
  62.             CASE -2
  63.                 IF rb = 0 THEN
  64.                     IF mydemo% THEN mydemo% = 4: GOSUB mydemo
  65.                     bactive = 0
  66.                 END IF
  67.             CASE -3
  68.                 IF mb = 0 THEN
  69.                     IF mydemo% THEN mydemo% = 5: GOSUB mydemo
  70.                     bactive = 0
  71.                 END IF
  72.         END SELECT
  73.     ELSE
  74.         IF lb THEN
  75.             IF mydemo% THEN mydemo% = 6: GOSUB mydemo
  76.             bactive = -1
  77.             z1 = TIMER
  78.         ELSEIF rb THEN
  79.             IF mydemo% THEN mydemo% = 7: GOSUB mydemo
  80.             bactive = -2
  81.         ELSEIF mb THEN
  82.             IF mydemo% THEN mydemo% = 8: GOSUB mydemo
  83.             bactive = -3
  84.         ELSEIF mw THEN
  85.             SELECT CASE mw
  86.                 CASE IS > 0
  87.                     IF mydemo% THEN mydemo% = 9: GOSUB mydemo
  88.                 CASE IS < 0
  89.                     IF mydemo% THEN mydemo% = 10: GOSUB mydemo
  90.             END SELECT
  91.         END IF
  92.     END IF
  93.     oldmx = mx: oldmy = my: mw = 0
  94.     EXIT SUB
  95.  
  96.     mydemo:
  97.     LOCATE 1, 1: PRINT "Last User Status:                                    ";
  98.     LOCATE , 19
  99.     SELECT CASE mydemo%
  100.         CASE 1
  101.             PRINT "1-byte keypress = "; b$
  102.         CASE 2
  103.             PRINT "2-byte keypress = "; b$
  104.         CASE 3
  105.             PRINT "Left button released."
  106.         CASE 4
  107.             PRINT "Right button released."
  108.         CASE 5
  109.             PRINT "Middle button released."
  110.         CASE 6
  111.             PRINT "Left button down."
  112.         CASE 7
  113.             PRINT "Right button down."
  114.         CASE 8
  115.             PRINT "Middle button down."
  116.         CASE 9
  117.             PRINT "Wheel scroll down."
  118.         CASE 10
  119.             PRINT "Wheel scroll up."
  120.         CASE 11
  121.             PRINT "Left button double click."
  122.         CASE 12
  123.             PRINT "Drag..."
  124.     END SELECT
  125.     mydemo% = -1
  126.     RETURN

I used a short sound to represent a left button double-click. All other mouse and wheel demos, including drag are printed to the screen. It is important to determine if your mouse routines will take effect upon button down or button release, and modify the code as needed for those specific circumstances.

As far as advice for SENDKEYS, just this. Remember that we can't easily get feedback for the automated key presses, and Windows loves to interrupt our routines with its many background processes, so don't expect short delays to always be sufficient Once an automated key press is missed, because the prior press wasn't processed quickly enough, the routine will fail.

Pete

EDIT: Changed it from a GOSUB to a SUB routine and improved the messaging display. Also, corrected + to - for midnight adjustment, darn aging process. Modified double click to register after the second left button press is released, instead of upon the second left button being pressed. This just makes it easier to display the double click message, without it being over-written with the left button release message. If I work on this more, I may make a user variable to designate any mouse action to act when button is down or act when the depressed button is released.
« Last Edit: October 05, 2021, 01:16:22 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #16 on: October 05, 2021, 02:17:23 am »
CTRL + ^ is one.
CTRL + [, and CTRL + ] are two more, I think.
CTRL +? as well...
_ and \  for the others?

But I don't remember the order now, off the top of my head.
No need to remember them, the character and the control character always differ by 64 on the ASCII chart (on old terminals, the Control key would just force a bit to 0).

Well, you have to lookup the characters on the ASCII table but we have one in the IDE.

Offline Richard

  • Seasoned Forum Regular
  • Posts: 364
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #17 on: October 05, 2021, 09:00:17 pm »
@Pete

I have been getting some more practice with your SENDKeys stuff (so far so good) - and now trying to expand into MOUSE stuff.

I have hit a problem with "focusing the mouse to an app".

In the program below what I have attempted to do was

- PROGRAM WINDOW  mouse around for 10 seconds
- switch over to NotePad
- for 10 seconds attempt to mouse around in NotePad
- finally let SENDKEYS do its magic

So far my problem is that I cannot get mouse co-ordinates in NotePad




Code: QB64: [Select]
  1. redim shared title$
  2. redim shared hwnd%&
  3. dim shared color_t~&&,color_m~&&
  4.     SUB      SENDKEYS             ALIAS keybd_event (BYVAL bVk AS LONG, BYVAL bScan AS LONG, BYVAL dwFlags AS LONG, BYVAL dwExtraInfo AS LONG)
  5.     FUNCTION FindWindowA%&        (BYVAL ClassName AS _OFFSET, WindowName$) 'find process handle by title
  6.     FUNCTION SetForegroundWindow& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
  7.  
  8. CONST KEYEVENTF_KEYUP = &H2
  9. CONST VK_SHIFT =        &H10 'Shift key
  10. CONST VK_CTRL =         &H11 ' Ctrl key
  11. CONST VK_ALT =          &H12 ' Alt key
  12.  
  13. NotePad:
  14. DEFLNG A-Z
  15. SCREEN _NEWIMAGE(640, 480, 32)
  16. _title "PROGRAM WINDOW":color &hffffff00~&&:locate 3,30:PRINT "This is PROGRAM WINDOW..."; : _DELAY 5
  17. color &hff00ff00~&&:locate 10,1:print "MOUSE around PROGRAM WINDOW for 10 seconds"
  18. color_t~&&=&hff00ff00~&&:color_m~&&=&hfffff000~&& :MouseAround
  19.  
  20. _delay 2:_screenclick 100,100: _delay .5
  21. title$=  "START NotePad.exe"                                                                            '*******************
  22. SHELL _DONTWAIT title$ 'opens Notepad file NOT MAXIMIZED
  23.  
  24. focusApp 'Focused on NotePad
  25. color &hffffffff~&&:play "L16N60"
  26. cls:locate 3,30:print "switch mouse focus to NotePad" :timerold = timer
  27. color &hff00ffff~&&:locate 10,1:print "MOUSE around PROGRAM WINDOW for 10 seconds"
  28. color_t~&&=&hff00ffff~&&:color_m~&&=&hffff0000~&& :MouseAround
  29.  
  30. _SCREENPRINT "HELLO WORLD":
  31. SLEEP 2:_SCREENPRINT CHR$(8) + CHR$(8) + CHR$(8) + CHR$(8) + CHR$(8) 'backspace 5 characters
  32. SLEEP 2:for i%=1 to 10:gosub Ctrl_Plus:next ' MAXIMUM NLARGEMENT of NotePad
  33. _SCREENPRINT CHR$(1) 'CTRL + A select all
  34. SLEEP 2:_SCREENPRINT CHR$(3) 'CTRL + C copy to clipboard
  35. _CLIPBOARD$ = "QB64 ROCKS!"''SLEEP 2
  36. _delay 2:_SCREENPRINT CHR$(22) 'CTRL + V paste from clipboard
  37.  
  38. Ctrl_Plus:
  39. SENDKEYS VK_CTRL, 0, 0, 0 ' Ctrl
  40. SENDKEYS &HBB, 0, 0, 0 ' +
  41. SENDKEYS &HBB, 0, KEYEVENTF_KEYUP, 0 ' Release +
  42. SENDKEYS VK_CTRL, 0, KEYEVENTF_KEYUP, 0 ' Release Ctrl
  43. _delay .2                                                                            '********************
  44.  
  45. SUB focusapp
  46. hwnd%& = FindWindowA(0, title$ + CHR$(0))
  47. z& = SetForegroundWindow&(hwnd%&)
  48.  
  49. SUB MouseAround
  50. timerold&=timer
  51.         mx=_mousex:my = _mousey:c&=point(mx,my)
  52.         locate 10,1:print space$(79);:locate 10,1:print _mousex;"x";_mousey;"y    ";hex$(c&)
  53.     loop
  54.     color color_t~&&:locate 10,75:print using "###";timerold+10-timer:color color_m~&&
  55. loop until timer > timerold& +10
  56.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #18 on: October 05, 2021, 09:29:14 pm »
Since you are no longer opening Notepad in full screen, you are having a problem focusing Notepad. The _SCREENCLICK needs to be placed at line 35.

color_t~&&=&hff00ffff~&&:color_m~&&=&hffff0000~&& :MouseAround
 _DELAY 2:_SCREENCLICK 100,100: _DELAY .5
_SCREENPRINT "HELLO WORLD":

Also, 100, 100 is only going to work if you have notepad open in the top left corner. That means you have to open Notepad manually, move it there, and close it.

I'd go with a Windows API focus by title. I believe "Untitled" is the Notepad default title. Provided there is only one copy of Notepad open, that should work. It's been at least two years since I've made a focus routine for Firefox, so I do not recall the code.

As for the mouse in QB64 finding coordinates in notepad, I do not believe that is conventionally possible. Notepad is not a QB64 program. For an unconventional approach, I suppose you could overlay a QB64 window, make it transparent, and measure the  mouse coordinates that way. This is often handy to see where a _SCREENCLICK should be made.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: _SCREENPRINT text$ Question
« Reply #19 on: October 05, 2021, 09:32:09 pm »
You can just use the SetFocus() Windows API function to set focus to the Notepad window and then do your typing. Much more dependable than relying on it being in a specific spot or what color it is. Also, you can use GetWindowRect() from Windows API to find the boundaries of the Notepad window. It will give the coordinates of each corner.
Shuwatch!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #20 on: October 05, 2021, 09:44:34 pm »
Thanks Indy, that's what I was getting at. Ah, here is a little screen mapper I put together a year or two ago...

Code: QB64: [Select]
  1. DEFINT A-Z
  2.  
  3. CONST HWND_TOPMOST%& = -1
  4. CONST SWP_NOSIZE%& = &H1
  5. CONST SWP_NOMOVE%& = &H2
  6. CONST SWP_SHOWWINDOW%& = &H40
  7.  
  8. DIM Hold AS POINTAPI
  9. TYPE POINTAPI
  10.     X_Pos AS LONG
  11.     Y_Pos AS LONG
  12.  
  13.     FUNCTION ShowWindow& (BYVAL hwnd AS _OFFSET, BYVAL nCmdShow AS LONG) 'maximize process
  14.     FUNCTION GetForegroundWindow& 'find currently focused process handle
  15.     FUNCTION SetForegroundWindow& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
  16.     FUNCTION SetLayeredWindowAttributes& (BYVAL hwnd AS LONG, BYVAL crKey AS LONG, BYVAL bAlpha AS _UNSIGNED _BYTE, BYVAL dwFlags AS LONG)
  17.     FUNCTION GetWindowLong& ALIAS "GetWindowLongA" (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG)
  18.     FUNCTION SetWindowLong& ALIAS "SetWindowLongA" (BYVAL hwnd AS LONG, BYVAL nIndex AS LONG, BYVAL dwNewLong AS LONG)
  19.     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)
  20.     FUNCTION GetAsyncKeyState% (BYVAL vkey AS LONG)
  21.     FUNCTION SetCursorPos (BYVAL x AS LONG, BYVAL y AS LONG)
  22.     FUNCTION GetCursorPos (lpPoint AS POINTAPI)
  23.  
  24. _CLIPBOARD$ = "" ' Clear clipboard.
  25.  
  26. ' Needed for acquiring the hWnd of the window
  27. DIM Myhwnd AS LONG ' Get hWnd value
  28. _TITLE "Translucent window test"
  29. Myhwnd = _WINDOWHANDLE
  30. wdth = 300: hght = 400
  31.  
  32. ' Set screen
  33. s& = _NEWIMAGE(wdth, hght, 32)
  34.  
  35. _SCREENMOVE 800, 50
  36. ' Main loop
  37. Level = 175
  38. SetWindowOpacity Myhwnd, Level
  39.  
  40. DIM logger$(100), logger2$(100)
  41.  
  42.     _LIMIT 30
  43.     msg = GetCursorPos(Hold)
  44.     LOCATE 1, 1: PRINT "Col ="; Hold.X_Pos;: LOCATE 1, 11: PRINT "Row ="; Hold.Y_Pos; "   ";
  45.     IF GetAsyncKeyState(1) THEN
  46.         IF flag THEN
  47.             cnt = cnt + 1
  48.             BEEP
  49.             logger$(cnt) = LTRIM$(STR$(Hold.X_Pos))
  50.             logger2$(cnt) = LTRIM$(STR$(Hold.Y_Pos))
  51.         ELSE
  52.             flag = -1
  53.         END IF
  54.     END IF
  55.     IF GetAsyncKeyState(&H1B) THEN
  56.         EXIT DO 'ESC key exits loop and prints logged key presses
  57.     END IF
  58.         IF oldimage& <> 0 THEN
  59.             oldimage& = s&
  60.             wdth = _RESIZEWIDTH: hght = _RESIZEHEIGHT
  61.             IF hght < 100 OR wdth < 150 THEN
  62.                 IF hght <= 100 THEN hght = 100
  63.                 IF wdth <= 150 THEN wdth = 150
  64.                 _RESIZE OFF
  65.                 _DELAY .2
  66.                 s& = _NEWIMAGE(wdth, hght, 32)
  67.                 SCREEN s&
  68.                 _DISPLAYORDER _SOFTWARE , _HARDWARE
  69.                 _FREEIMAGE oldimage&
  70.                 _RESIZE ON
  71.             ELSE
  72.                 s& = _NEWIMAGE(wdth, hght, 32)
  73.                 SCREEN s&
  74.                 _FREEIMAGE oldimage&
  75.             END IF
  76.             LOCATE 4, 1
  77.             PRINT mystring$;
  78.         ELSE
  79.             oldimage& = s&
  80.         END IF
  81.     END IF
  82.  
  83.     b$ = INKEY$
  84.     IF LEN(b$) THEN
  85.         IF b$ = CHR$(27) THEN SYSTEM
  86.         IF LEN(b$) = 2 THEN
  87.             IF b$ = CHR$(0) + CHR$(59) AND Level < 255 THEN Level = Level + 1: SetWindowOpacity Myhwnd, Level
  88.             IF b$ = CHR$(0) + CHR$(60) AND Level > 0 THEN Level = Level - 1: SetWindowOpacity Myhwnd, Level
  89.             yy = CSRLIN: xx = POS(0): LOCATE 1, 1: PRINT "Press F1/F2 to change opacity"; Level;: LOCATE yy, xx
  90.         ELSE
  91.             PRINT b$;
  92.             mystring$ = mystring$ + b$
  93.         END IF
  94.     END IF
  95.     _DISPLAY
  96. FOR i = 0 TO cnt
  97.     PRINT "_SCREENCLICK "; logger$(i); ", "; logger2$(i)
  98.  
  99. '====================================================================\
  100. SUB SetWindowOpacity (hwnd AS LONG, Level)
  101.     DIM Msg AS LONG
  102.     CONST G = -20
  103.     CONST LWA_ALPHA = &H2
  104.     CONST WS_EX_LAYERED = &H80000
  105.     Msg = GetWindowLong(hwnd, G)
  106.     Msg = Msg OR WS_EX_LAYERED
  107.     action = SetWindowLong(hwnd, G, Msg)
  108.     action = SetLayeredWindowAttributes(hwnd, 0, Level, LWA_ALPHA)
  109.  

It makes a translucent window, which you can size over an app, and find the screenclick coordinates by mousing to the point, left clicking, and press esc when you have all the stuff mapped to see a list of the coordinates in the QB64 program window.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: _SCREENPRINT text$ Question
« Reply #21 on: October 05, 2021, 09:45:13 pm »
Oops. Yep, can't use SetFocus. Wrong function. It's SetForegroundWindow. Yep.
Shuwatch!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #22 on: October 05, 2021, 10:14:24 pm »
I just found my FireFox set focus routine...

Code: QB64: [Select]
  1. ct]
  2.  
  3.     DECLARE DYNAMIC LIBRARY "user32"
  4.         FUNCTION FindWindowA%& (BYVAL ClassName AS _OFFSET, WindowName$) 'handle by title
  5.         FUNCTION ShowWindow& (BYVAL hwnd AS _OFFSET, BYVAL nCmdShow AS LONG) 'maximize process
  6.         FUNCTION SetForegroundWindow& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
  7.         FUNCTION GetForegroundWindow%& 'find currently focused process handle
  8.     END DECLARE
  9.      
  10.     _SCREENMOVE 300, 200
  11.     title$ = "hwnd Finder"
  12.     _TITLE title$
  13.     find$ = "Bing - mozilla firefox" ' Works but you need active window displayed.
  14.     findqb$ = title$
  15.     SHELL _HIDE "firefox.exe bing.com"
  16.     _DELAY 5
  17.     GOSUB focus
  18.     PRINT "Make Firefox window size and press any key to minimize."
  19.     PRINT "It will restore in 5 sec."
  20.     SLEEP
  21.     x& = ShowWindow&(hwnd%&, 2)
  22.     _DELAY 5
  23.     ' 0 closes app. 1 restores app. 2 minimizes app. 3 maximizes app.
  24.     y& = ShowWindow&(hwnd%&, 1)
  25.     _DELAY .1
  26.     GOSUB focus
  27.     PRINT "Press any key to Maximize Firefox."
  28.     SLEEP
  29.     y& = ShowWindow&(hwnd%&, 3)
  30.     _DELAY .1
  31.     GOSUB focus
  32.     PRINT "Press any key to Close Firefox."
  33.     SLEEP
  34.     y& = ShowWindow&(hwnd%&, 0)
  35.     END
  36.      
  37.     focus:
  38.     hwnd%& = FindWindowA(0, findqb$ + CHR$(0))
  39.     _DELAY .1
  40.     FGwin%& = GetForegroundWindow%& 'get current process in focus
  41.     _DELAY .1
  42.     IF FGwin%& <> hwnd%& THEN z& = SetForegroundWindow&(hwnd%&) 'set focus when necessary
  43.     _DELAY .1
  44.     hwnd%& = FindWindowA(0, find$ + CHR$(0))
  45.     _DELAY .1
  46.     RETURN
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Richard

  • Seasoned Forum Regular
  • Posts: 364
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #23 on: October 05, 2021, 11:01:28 pm »
@Pete

Just tried out simple changes (have not read/studied replies from @Pete @SpriggsySpriggs yet)

Tried the TRANSPARENT window effect ( i.e. without out the screen mode color at end  so have SCREEN NEWIMAGE(640,480).

This defaults to a SCREEN 0 (more correctly a TEXT SCREEN) - that's OK just means that color 0-31 only and co-ords as per character cell positions (not display pixels).


The TRANSPARENT window is 3200 x 1800 pixels (my native display resolution) and I on purpose offset down to _SCREENMOVE 10,110  (NOTHING to go in top 100 pixel scan rows). When NotePad comes into action - SOMETIMES it is on TOP else underneath the BLACK TRANSPARENT window where I can not see it. Manually I preset NotePad to 0,100 so I always know where the extreme Top Left Hand Corner of NotePad is.  In my way of thinking TRANSPARENT here is more of place a blackboard here instead (Transparent I myself think of simultaneously seeing all the layers underneath).

Apart from a "very jerky sluggish" mouse response (like say 1000 times slower) and maybe updates every 3 seconds or so (which would probably be still OK in my program automation (I wont be at the keyboard most of the time) - I notice that on the 50% of times when NotePad is on TOP that it seems that I have to move the mouse outside of the NotePad region (causing NotePad to go on bottom) and then having the "BLACKBOARD" (TRANSPARENT WINDOW) only I can mouse arround (very slowly).

Thanks for the tip on this unconventional approach.

Just wondering - any way (eg by setting alpha values for all 3200x1800 pixels) that I can change the "BLACKBOARD" to "plain cellophane" as the TRANSPARENT window.

So the above appears somewhat "potentially useable" for me - will try to refine further.  Then to "digest" info from your replies above.

Offline Richard

  • Seasoned Forum Regular
  • Posts: 364
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #24 on: October 05, 2021, 11:35:10 pm »
@Pete @SpriggsySpriggs

My program at this stage (subject to change by your advice from above)


Code: QB64: [Select]
  1. redim shared title$
  2. redim shared hwnd%&
  3.  
  4.     SUB      SENDKEYS             ALIAS keybd_event (BYVAL bVk AS LONG, BYVAL bScan AS LONG, BYVAL dwFlags AS LONG, BYVAL dwExtraInfo AS LONG)
  5.     FUNCTION FindWindowA%&        (BYVAL ClassName AS _OFFSET, WindowName$) 'find process handle by title
  6.     FUNCTION SetForegroundWindow& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
  7.  
  8. CONST KEYEVENTF_KEYUP = &H2
  9. CONST VK_SHIFT =        &H10 'Shift key
  10. CONST VK_CTRL =         &H11 ' Ctrl key
  11. CONST VK_ALT =          &H12 ' Alt key
  12.  
  13. NotePad:
  14. DEFLNG A-Z
  15. SCREEN _NEWIMAGE(640, 480)', 32)by ommiting screen modes --> TRANSPARENT
  16. _screenmove 10,110 ' attempt to make PROGRAM WINDOW transparent
  17. _title "PROGRAM WINDOW":
  18. color 14:locate 3,30:PRINT "This is PROGRAM WINDOW...";
  19. color 10:locate 5,1:print "MOUSE around PROGRAM WINDOW for 10 seconds"
  20. MouseAround
  21. title$=  "START NotePad.exe"                                                                            '*******************
  22. SHELL _DONTWAIT title$ 'opens Notepad file NOT MAXIMIZED
  23.  
  24. focusApp 'Focused on NotePad
  25. play "L16N60":cls
  26. color 31:locate 3,30:print "switch mouse focus to NotePad" :timerold = timer
  27. color 14:locate 5,1:print "MOUSE around PROGRAM WINDOW for 20 seconds"
  28. MouseAround
  29. _delay 2:_screenclick 300,300: _delay .5
  30. _SCREENPRINT "HELLO WORLD":
  31. SLEEP 2:_SCREENPRINT CHR$(8) + CHR$(8) + CHR$(8) + CHR$(8) + CHR$(8) 'backspace 5 characters
  32. SLEEP 2:for i%=1 to 10:gosub Ctrl_Plus:next ' MAXIMUM NLARGEMENT of NotePad
  33. _SCREENPRINT CHR$(1) 'CTRL + A select all
  34. SLEEP 2:_SCREENPRINT CHR$(3) 'CTRL + C copy to clipboard
  35. _CLIPBOARD$ = "QB64 ROCKS!"''SLEEP 2
  36. _delay 2:_SCREENPRINT CHR$(22) 'CTRL + V paste from clipboard
  37.  
  38. Ctrl_Plus:
  39. SENDKEYS VK_CTRL, 0, 0, 0 ' Ctrl
  40. SENDKEYS &HBB, 0, 0, 0 ' +
  41. SENDKEYS &HBB, 0, KEYEVENTF_KEYUP, 0 ' Release +
  42. SENDKEYS VK_CTRL, 0, KEYEVENTF_KEYUP, 0 ' Release Ctrl
  43. _delay .2                                                                            '********************
  44.  
  45. SUB focusapp
  46. hwnd%& = FindWindowA(0, title$ + CHR$(0))
  47. z& = SetForegroundWindow&(hwnd%&)
  48.  
  49. SUB MouseAround
  50. timerold&=timer
  51.         mx=_mousex:my = _mousey:locate 5,4:print space$(70);
  52.         locate 5,5:print _mousex;"x";_mousey;"y    "
  53.     loop
  54.     color 26:locate 5,1:print using "###";timerold+20-timer:color 15
  55. loop until timer > (timerold& +20)
  56.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #25 on: October 06, 2021, 01:13:14 am »
Try this demo to see how focus to an Untitled Notepad is done.

Code: QB64: [Select]
  1.     FUNCTION FindWindowA%& (BYVAL ClassName AS _OFFSET, WindowName$) 'handle by title
  2.     FUNCTION ShowWindow& (BYVAL hwnd AS _OFFSET, BYVAL nCmdShow AS LONG) 'maximize process
  3.     FUNCTION SetForegroundWindow& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
  4.     FUNCTION GetForegroundWindow%& 'find currently focused process handle
  5.  
  6. title$ = "myprog"
  7. _TITLE (title$)
  8.  
  9. SHELL _DONTWAIT "notepad"
  10.  
  11.     title$ = "myprog"
  12.  
  13.     PRINT "Any key to focus on Notepad": GOSUB focus
  14.  
  15.     SLEEP
  16.  
  17.     title$ = "Untitled - Notepad"
  18.  
  19.     PRINT "Click here to focus on QB64.": GOSUB focus
  20.  
  21.     DO
  22.         _LIMIT 30
  23.         WHILE _MOUSEINPUT: WEND
  24.         IF _MOUSEBUTTON(1) THEN EXIT DO
  25.     LOOP
  26.  
  27. focus:
  28. hwnd%& = FindWindowA(0, title$ + CHR$(0))
  29. FGwin%& = GetForegroundWindow%& 'get current process in focus
  30. IF FGwin%& <> hwnd%& THEN z& = SetForegroundWindow&(hwnd%&) 'set focus when necessary
  31. hwnd%& = FindWindowA(0, find$ + CHR$(0))
  32.  

Note in the focus sub, I just changed the findqb$ variable from my Firefox routine to titles$, for simplicity. Also, when you use a Windows focus routine, you should lose the _SCREENCLICK statement.

Pete

Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #26 on: October 06, 2021, 02:15:57 am »
@Richard Your routine crashed my system, twice. I rewrote it below. It's a s close as I could approximate to what it looked like you tried to achieve.

Code: QB64: [Select]
  1. REDIM SHARED title$
  2. REDIM SHARED hwnd%&
  3.  
  4.     SUB SENDKEYS ALIAS keybd_event (BYVAL bVk AS LONG, BYVAL bScan AS LONG, BYVAL dwFlags AS LONG, BYVAL dwExtraInfo AS LONG)
  5.     FUNCTION FindWindowA%& (BYVAL ClassName AS _OFFSET, WindowName$) 'handle by title
  6.     FUNCTION ShowWindow& (BYVAL hwnd AS _OFFSET, BYVAL nCmdShow AS LONG) 'maximize process
  7.     FUNCTION SetForegroundWindow& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
  8.     FUNCTION GetForegroundWindow%& 'find currently focused process handle
  9.  
  10. CONST KEYEVENTF_KEYUP = &H2
  11. CONST VK_SHIFT = &H10 'Shift key
  12. CONST VK_CTRL = &H11 ' Ctrl key
  13. CONST VK_ALT = &H12 ' Alt key
  14.  
  15. NotePad:
  16. DEFLNG A-Z
  17. SCREEN _NEWIMAGE(640, 480, 32)
  18. _SCREENMOVE 10, 110
  19. _TITLE "PROGRAM WINDOW"
  20.  
  21. COLOR &HFF00FF00~&&
  22. LOCATE 5, 1: PRINT "MOUSE around PROGRAM WINDOW for 10 seconds"
  23.  
  24. MouseAround
  25.  
  26. SHELL _HIDE _DONTWAIT "start Notepad" 'opens Notepad file NOT MAXIMIZED
  27.  
  28. PLAY "L16N60": CLS
  29. LOCATE 3, 30: PRINT "switch mouse focus to NotePad": timerold = TIMER
  30. LOCATE 5, 1: PRINT "MOUSE around PROGRAM WINDOW for 10 seconds"
  31. MouseAround
  32.  
  33. title$ = "Untitled - Notepad": focusapp 'Focused on NotePad
  34.  
  35. _SCREENPRINT "HELLO WORLD":
  36. SLEEP 2: _SCREENPRINT CHR$(8) + CHR$(8) + CHR$(8) + CHR$(8) + CHR$(8) 'backspace 5 characters
  37. SLEEP 3: _SCREENPRINT "QB64!"
  38. SLEEP 2: FOR i% = 1 TO 10: GOSUB Ctrl_Plus: NEXT ' MAXIMUM NLARGEMENT of NotePad
  39. _SCREENPRINT CHR$(1) 'CTRL + A select all
  40. SLEEP 2: _SCREENPRINT CHR$(3) 'CTRL + C copy to clipboard
  41. _CLIPBOARD$ = "QB64 ROCKS!" ''SLEEP 2
  42. _DELAY 2: _SCREENPRINT CHR$(22) 'CTRL + V paste from clipboard
  43.  
  44. Ctrl_Plus:
  45. SENDKEYS VK_CTRL, 0, 0, 0 ' Ctrl
  46. SENDKEYS &HBB, 0, 0, 0 ' +
  47. SENDKEYS &HBB, 0, KEYEVENTF_KEYUP, 0 ' Release +
  48. SENDKEYS VK_CTRL, 0, KEYEVENTF_KEYUP, 0 ' Release Ctrl
  49. _DELAY .2 '********************
  50.  
  51. SUB focusapp
  52.     hwnd%& = FindWindowA(0, title$ + CHR$(0))
  53.     _DELAY .1
  54.     FGwin%& = GetForegroundWindow%& 'get current process in focus
  55.     _DELAY .1
  56.     IF FGwin%& <> hwnd%& THEN z& = SetForegroundWindow&(hwnd%&) 'set focus when necessary
  57.     _DELAY .1
  58.  
  59. SUB MouseAround
  60.     timerold& = TIMER
  61.     LOCATE 5, 1: PRINT SPACE$(_WIDTH);
  62.     DO
  63.         _LIMIT 120
  64.         WHILE _MOUSEINPUT: WEND
  65.         mx = _MOUSEX: my = _MOUSEY
  66.         LOCATE 5, 5: PRINT _MOUSEX; "x"; _MOUSEY; "y    "
  67.         LOCATE 5, 1: PRINT USING "###"; timerold + 10 - TIMER
  68.     LOOP UNTIL TIMER > (timerold& + 10)

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: _SCREENPRINT text$ Question
« Reply #27 on: October 06, 2021, 04:23:07 am »
If you guys use PowerShell, you can use Get-Location or Get-UiaWindow to get the exact coordinates for your notepad.exe on the screen. 

Code: [Select]
$test = Start-Process notepad.exe -PassThru | Get-UiaWindow #| Get-UiaCurrentPattern -PassThru

$test.Current.BoundingRectangle

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-location?view=powershell-7.1
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Richard

  • Seasoned Forum Regular
  • Posts: 364
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #28 on: October 06, 2021, 07:20:33 am »



   

@Pete  - sorry to have crashed your computer twice! (I did not mean that to happen)


@Pete @SpriggsySpriggs @SMcNeill



Sorry - I think you are on a different "wavelength" from me - this may be because I have not explained myself very well and/or the example provided is not clear and detailed enough.


I think that @Pete saying that "NotePad is not a QB64 program" sums up the situation (and those words may echo in my mind for the next 25 years). I gather that because NotePad is not a program created by QB64, then now it cannot be truely focused on (I hope I am very wrong with this statement). So far, to date, SENDKEYS seems to be able to focus onto NotePad (i.e. via my QB64 program I can get to do some simple things such as Ctrl+ to enlarge the text) - rather than me being at the keyboard performing those same keystrokes.

If I may restate my program requirements (with a very silly example to hopefully clarify better).


Solely by virtue of my QB64 program alone (i.e. once launched I am not present at the keyboard)....



- open up a QB64 Program window (NOTHING ever to occupying the top 100 scan lines of display)

- for 10 seconds display mouse coordinates (if mouse cursor is over the program window - so if a cat played with the mouse during this time, it is reflected in displayed mouse movements)

- switch over to NotePad (idealy NOT MAXIMIZED - however if this cannot work I would allow it to be MAXIMIZED)

- for 10 seconds display mouse co-ordinates (if mouse cursor is over the non-maximized NotePad window) - i.e. now the co-ords displayed are only with regard to NotePad

- do some SENDKEYS magic ( Ctrl + ) to enlarge the NotePad text area - NOTHING ELSE (so therefore no changes to untitled.txt)

- if mouse is truely "focused" to NotePad - my QB64 program should be able to re-locate the mouse cursor to the Top Right Hand Corner of NotePad (which I would have established experimentally the co-ords of same before hand) and CLOSE NotePad (without me being at keyboard).




Assuming the above can be achieved, then eventually other things such as the color at a certain pixel of NotePad, actually write into NotePad the co-ords where the mouse cursor was at the time in NotePad (or better output to a separate file), minimize the NotePad window, etc could be done I hope.



@Pete regarding your demo program (although not doing the mouse thing as outlined above) - there were problems of no response after the first set of switching "focus" from Program window to NotePad Window. Also having _CLIPBOARD$ = "" made programs a bit more robust (in my case not displaying edits of my program onto the Program Window display).


With regards to the un-conventional TRANSPARENT window overlay (which I call a BLACKBOARD) - I discovered that I cannot even manually operate the mouse "click through" the BLACKBOARD to close NotePad (when NotePad is not on top) - so I do not have a potentially useable system as previously stated. So maybe all this TRANSPARENT stuff only relates to QB64 programs only ???



@SMcNeill    I have never used PowerShell before (have used QB64 SHELL cmd stuff tons of time) - could you provide QB64 code example how to use PowerShell please?

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: _SCREENPRINT text$ Question
« Reply #29 on: October 06, 2021, 11:30:22 am »
All this mouseing around crap is about just wanting to close Notepad????!!!!!!!!!!!!!!!!!!

ARHHHHHHHHHH!

WARNING: THIS KILL EVERY INSTANCE OF NOTEPAD OPEN ON YOUR COMPUTER WITHOUT PROMPTING YOU TO SAVE. IF YOU HAVE OTEHR INSTANCES OF UNSAVED NOTEPAD FILES ON YOUR DESKTOP, SAVE THEM AND CLOSE THEM BEFORE RUNNING THIS CODE.

Code: QB64: [Select]
  1. SHELL _HIDE "taskkill /f /im notepad.exe"
  2.  

That kills ALL Notepad opened. It forces them shut, even though writing to it would normally ask you if you wanted it saved.

Also, you can use sendkeys to send Alt+F then x then n. The n is for "Don't Save"

Pete :D

« Last Edit: October 06, 2021, 11:38:43 am by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/