Announcement

Collapse
No announcement yet.

Changing focus

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mark Hunter
    replied
    They’re Windows “messages” instead of API calls.

    I see that I misunderstood you when you wrote
    “the user may click the mouse in the graphics window, thus changing focus to the graphics window.”
    I took that to mean you were capturing the mouse, but you’re not.

    It’s possible to capture mouse and keyboard activity in a graphic window. (I seem to be posting a lot about this, but obviously this is useful.) The following is a very simple example.
    ' Compiler: PBCC 4.04 (not 4.03)

    #Dim All
    '-----------------------------------------------------------------

    Macro False = 0
    Macro True = -1
    Macro Boolean = Long
    '-----------------------------------------------------------------

    'From WinAPI
    %WM_KEYDOWN = &H100
    %WM_KEYUP = &H101
    %GWL_WNDPROC = -4

    %VK_OEM_COMMA = &HBC
    %VK_OEM_PERIOD = &HBE

    %WM_NCHITTEST = &H084
    %HTTRANSPARENT = -1
    %WM_LBUTTONDOWN = &H201
    %WM_RBUTTONDOWN = &H204
    %WM_LBUTTONUP = &H202
    %WM_RBUTTONUP = &H205
    %GW_CHILD = 5
    %HTCLIENT = 1

    Declare Function GetWindow Lib "USER32.DLL" Alias "GetWindow" (ByVal Wnd As Dword, ByVal wCmd As Dword) As Long
    Declare Function CallWindowProc Lib "USER32.DLL" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Dword, ByVal Wnd As Dword, ByVal uMsg As Dword, ByVal param As Dword, ByVal mousepos As Long) As Long
    Declare Function SetWindowLong Lib "USER32.DLL" Alias "SetWindowLongA" (ByVal Wnd As Dword, ByVal nIndex As Long, ByVal lNewLong As Long) As Long
    '=================================================================

    %esc = 27 ' ascii keycode for escape key
    %leftbutton = 1 'arbitrary whichbutton values
    %rightbutton = -1
    %nobutton = 0
    '-----------------------------------------------------------------

    Declare Function GWnew(ByVal Dword, ByVal Dword, ByVal Dword, ByVal Long) As Long
    Declare Function InStat1 As Long
    Declare Function InKey1 As Long
    Declare Sub StuffKey(ByVal Long)
    Declare Sub Getkey
    Declare Sub MouseClick(ByVal Long)
    '-----------------------------------------------------------------

    Global GW, GWold As Dword 'handles
    Global win1 As Dword 'handle for window
    Global keybuff() As Long 'keycode buffer
    Global nkey As Long 'number of keys in keycode buffer
    Global whichbutton As Long 'which mouse button
    Global Xmouse, Ymouse As Long '(not used in this example code)
    Global exitcode As Long
    '-----------------------------------------------------------------

    Sub MouseClick(ByVal whichbutton As Boolean)
    If whichbutton = %leftbutton Then
    Print "Left button at ";Xmouse;Ymouse
    Else '%rightbutton
    Print "Right button at ";Xmouse;Ymouse
    End If
    End Sub

    Sub keyPress(ky As Long)
    If ky = Asc($Cr) Then
    Print
    Else
    Print Chr$(ky);
    End If
    End Sub
    '-----------------------------------------------------------------

    Function GWnew (ByVal Wnd As Dword, ByVal Msg As Dword, ByVal param As Dword, ByVal mousepos As Long) As Long
    Local result As Long

    result = CallWindowProc (GWold, Wnd, Msg, param, mousepos)

    Select Case Long Msg
    Case %WM_NCHITTEST
    If result = %HTTRANSPARENT Then result = %HTCLIENT

    Case %WM_LBUTTONDOWN
    whichbutton = %leftbutton
    Xmouse = Lo(Word,mousepos) :Ymouse = Hi(Word,mousepos)
    Case %WM_LBUTTONUP
    whichbutton = %nobutton
    Xmouse = Lo(Word,mousepos) :Ymouse = Hi(Word,mousepos)
    MouseClick %leftbutton

    Case %WM_RBUTTONDOWN
    whichbutton = %rightbutton
    Xmouse = Lo(Word,mousepos) :Ymouse = Hi(Word,mousepos)
    Case %WM_RBUTTONUP
    whichbutton = %nobutton
    Xmouse = Lo(Word,mousepos) :Ymouse = Hi(Word,mousepos)
    MouseClick %rightbutton

    Case %WM_KEYDOWN
    If param = %esc Then exitcode = true
    KeyPress Param 'always uppercase

    End Select

    Function = result
    End Function
    '-----------------------------------------------------------------

    Function PBMain
    Local GW As Dword

    Graphic Window "", 0,0, 400, 400 To win1 'create graphic window
    Graphic Attach win1, 0, ReDraw
    Graphic Set Focus
    Console Set Loc 400, 0

    GW = GetWindow(win1, %GW_CHILD) 'subclass
    GWold = SetWindowLong(GW, %GWL_WNDPROC, CodePtr(GWnew))

    whichbutton = %nobutton

    Graphic Print " Press Esc to quit.
    Graphic ReDraw

    Do
    If exitcode Then Exit Function
    Sleep 0
    Loop
    End Function
    For a more realistic example, involving only the keyboard, see the second post of
    http://powerbasic.com/support/pbforu...088#post270088
    For a complicated example, involving both the keyboard and mouse, see
    http://powerbasic.com/support/pbforu...ad.php?t=35575
    You can strip out the mouse-repeat part if you don't need it.

    Leave a comment:


  • Mark Buehnerkemper
    replied
    You're correct, I'm using the console for keyboard input, but at times do move the console into view for user input.

    Being new to PBCC, I'm not familiar with Case %WM_KEYDOWN or Case %WM_KEYUP and cant find them in the PBCC help system. Are these API calls?

    Leave a comment:


  • Mark Hunter
    replied
    The console is still active and receiving input from the keyboard, but is positioned off of the visible desktop.
    Sounds like you’re using the console just to capture keyboard activity.
    Since you must already be subclassing so that the graphic window captures mouse activity, it’s also capturing keyboard activity. Couldn't you check for Case %WM_KEYDOWN or Case %WM_KEYUP and dispense with the console entirely (#Console Off)?

    Leave a comment:


  • Mark Buehnerkemper
    replied
    Beautiful!

    That's exactly what I'm looking for. Thanks Much Pierre.

    Is there also a simple way to hide the mouse cursor until there is mouse movement? Or better yet, do you have a good reference for API calls so I can figure this out for myself!

    Guy... Thanks for your suggestion.

    I've looked at Console Tools, but do so little programming that didn't feel it would be a reasonable investment. This project is a rewrite from a PB3.5 program that I use daily in my work, and I have only gone back to programming after several years because the program has issues with newer graphics hardware. I'm having a blast with programming again, though, and may make the investment if I come up with more projects.

    Mark

    Leave a comment:


  • Pierre Bellisle
    replied
    Mark,
    Is this what you have in mind ?

    Code:
    #COMPILE EXE '#CC 4.04#
    #DIM ALL
    #INCLUDE "Win32Api.inc" '#2005-01-27#
     
    FUNCTION PBMAIN () AS LONG
     LOCAL DesktopRc   AS RECT
     LOCAL hWin        AS DWORD
     LOCAL sKey        AS STRING
     
     SystemParametersInfo %SPI_GETWORKAREA, 0, BYVAL VARPTR(DesktopRc), 0
     GRAPHIC WINDOW "Window", DesktopRc.nLeft, DesktopRc.nTop, DesktopRc.nRight, DesktopRc.nBottom TO hWin
     GRAPHIC ATTACH hWin, 0
     
     STDOUT "Focus always set to console and not to graphic window."
     STDOUT "Console can be minimized."
     STDOUT "Type Escape to end"
     DO
       IF GetForeGroundWindow = hWin THEN CONSOLE SET FOCUS
       IF IsIconic(CONSHNDL) THEN
         ShowWindow hWin, %SW_HIDE
       ELSE
         ShowWindow hWin, %SW_SHOW
       END IF
       sKey = INKEY$
       IF LEN(sKey) THEN STDOUT sKey;
       SLEEP 50
     LOOP UNTIL sKey = $ESC
     
    END FUNCTION

    Leave a comment:


  • Guy Dombrowski
    replied
    Console focus

    Mark,

    Get yourself a copy of Console Tools from Perfect Sync

    Leave a comment:


  • Mark Buehnerkemper
    replied
    Thanks, Mark, but I'm afraid I wasn't quite clear enough.

    I use CONSOLE SET FOCUS quite a bit, but the program (console) doesn't always know when it is needed.

    My current application has a graphics window that is scaled to fill the screen. The console is still active and receiving input from the keyboard, but is positioned off of the visible desktop.

    While the console is waiting for keyboard input, the user may click the mouse in the graphics window, thus changing focus to the graphics window. That's when I need to call CONSOLE SET FOCUS.

    I could simply continue to call CONSOLE SET FOCUS repeatedly as the program runs, but then the user wouldn't be able to run other applications without the console taking the focus back.

    I'm really looking for a way for the program to be able to recognize which window has focus, and use CONSOLE SET FOCUS each time the subordinate graphics window gets a mouse click or is activated using alt-tab switching.

    Thanks,

    Mark

    Leave a comment:


  • Mark Hunter
    replied
    Console Set Focus

    Leave a comment:


  • Mark Buehnerkemper
    started a topic Changing focus

    Changing focus

    When a graphics window gains focus directly from the user via mouse click or alt-tab switching, is there a simple way to automatically shift the focus over to the console window?

    Thanks,

    Mark
Working...
X