Semen, Thank you very much for the example code on using SetWindowsHookEx function. I will use the second example in my program that has DDT controls. I found code that simulates pressing keys in a program and used it in my program that has textboxes created using WIN32API calls. Jeffrey.
------------------
Announcement
Collapse
No announcement yet.
Pressing button or key
Collapse
X
-
Jeffrey --
You can find necessary information about keyboard hook, starting with http://msdn.microsoft.com/library/ps...hooks_8k6b.htm
In this sample program imitates button's click, when you press digits 1-9 on numpad.
Code:#Compile Exe #Register None #Dim All #Include "win32Api.inc" Global ghKbrdHook As Long Global lpfnKbrdHook As Long Global hDlg As Long Function KeyboardHook(ByVal iCode As Integer, ByVal wParam As Long, ByVal lParam As Long) As Dword If iCode = %HC_ACTION Then Select Case wParam Case %VK_NUMPAD1 To %VK_NUMPAD9 ' NumPad 1-9 If (lParam And &H80000000) = 0 Then _ Control Send hDlg, wParam - %VK_NUMPAD1 + 101, %BM_CLICK, 0, 0 End Select Function = 1: Exit Function ' sample of ignoring !!! End If Function = CallNextHookEx(ghKbrdHook, iCode, wParam, lParam) End Function CallBack Function Cb Select Case CbMsg Case %WM_INITDIALOG ghKbrdHook = SetWindowsHookEx(%WH_KEYBOARD, CodePtr(KeyboardHook), _ 0, GetCurrentThreadId) Case %WM_DESTROY: UnhookWindowsHookEx ghKbrdHook Case %WM_COMMAND If CbCtl >=101 And CbCtl <= 109 Then _ SetWindowText CbHndl, "[" + Str$(CbCtl - 100) + " ] " + Time$ End Select End Function Function PbMain Local i As Long Dialog New 0,"Test",,, 100, 180, %ws_sysmenu To hdlg For i = 1 To 9 Control Add Button, hdlg,100+ i, "Button" + Str$(i), 10, i * 15 - 10, 80, 12, %WS_BORDER Next Dialog Show Modal hdlg Call Cb End Function
Code:#Compile Exe #Register None #Dim All #Include "win32Api.inc" Global gHook As Long Global hDlg As Long Sub ButtonClicked (i As Integer) SetWindowText hDlg, "Button" + Str$(i) + " " + Time$ End Sub Function SysMsgProc(ByVal nCode As Integer, ByVal wParam As Long, Msg As tagMsg Ptr) As Long If nCode = %MSGF_DIALOGBOX Then If @Msg.Message = %WM_CHAR Then Select Case Chr$(@Msg.wParam) Case "1" To "9" ButtonClicked @Msg.wParam - Asc("0") Function = 1: Exit Function ' sample of ignoring !!! End Select End If End If Function = CallNextHookEx(gHook, nCode, wParam, Msg) End Function CallBack Function Cb Select Case CbMsg Case %WM_INITDIALOG gHook = SetWindowsHookEx(%WH_MSGFILTER, CodePtr(SysMsgProc), _ 0, GetCurrentThreadId) Case %WM_DESTROY: UnhookWindowsHookEx gHook Case %WM_COMMAND If CbCtl >= 101 And CbCtl <= 109 Then ButtonClicked CbCtl - 100 End Select End Function Function PbMain Local i As Long Dialog New 0,"Test",,, 100, 180, %ws_sysmenu To hdlg For i = 1 To 9 Control Add Button, hdlg,100 + i, "Button" + Str$(i), 10, i * 15 - 10, 80, 12, %WS_BORDER Next Dialog Show Modal hdlg Call Cb End Function
[This message has been edited by Semen Matusovski (edited April 06, 2000).]
Leave a comment:
-
I may be a day late and a dollar short hereHowever, I just wanted to put my piece in:
On my Options dialog box, if a user presses OK I want the same function to happen as if he pressed "Apply", and I got lazy so I said, hmmmmmmmm rather than write a new function just send a BN_CLICK message:
Code:Case %IDOK, 130 'OK 'Resume normal procedure after install is complete: If g_lInstallingFlag = 1 Then g_lInstallingFlag = 0 SaveSetting %HK,g_sInstKey,"ApplicationName",g_sWinLogEXE SaveSetting %HK,g_sInstKey,"DisplayName",g_szMINE SaveSetting %HK,g_sInstKey,"UninstallString",g_sWinLogFilePath & "wUnwise.exe" SaveSetting %HK,g_sMainKey, g_sInstallDir,g_sWinLogFilePath End If 'Click the Apply button If IsWindowEnabled(GetDlgItem(CbHndl,132)) Then SendMessage GetDlgItem(CbHndl,132) , %BM_CLICK, 0, 0 Dialog End CbHndl, 1 Exit Function
------------------
Scott
mailto:[email protected][email protected]</A>
Leave a comment:
-
Semen, How can I use SetWindowHook function? Jeffrey.
------------------
Leave a comment:
-
I didn't know that if PB/DLL program has DDT controls, it can't process keystrokes unless you subclass the controls.
about what you ?
There are at least three ways :
1) my "experimental" variant (during two monthes nobody said that there are problems with it)
2) Lance's variant of subclassing (see Source code forum) -
through initial callback function
3) SetWindowHook
------------------
Leave a comment:
-
Colin, I don't think that you will lose your posting privileges unless you say bad words to someone. I got confused over the differences between PB/DLL and Visual BASIC. I didn't know that if PB/DLL program has DDT controls, it can't process keystrokes unless you subclass the controls. Jeffrey.
------------------
Leave a comment:
-
Adam, Please see my reply to Lance about my model train layout. Jeffrey.
------------------
Leave a comment:
-
Lance, I won't add push buttons and radio buttons to my program because the code that processes keystrokes won't work with controls created using DDT. I will have to write the program using WIN32API calls. I wish that I would put the keyboard, mouse, and monitor next to control panel for my model train layout but I have to build shelves for the monitor, keyboard, and mouse and I need extension cables for monitor, keyboard, and mouse. Right now, my computer desk is about six feet from the control panel for my model train layout. Because of the furniture in my bedroom, the tracks are about six feet off the floor and I need a drafting chair with its seat raised all the way up to sit at the control panel. I may buy a remote control that controls the transformer using a receiver. Jeffrey.
------------------
Leave a comment:
-
Adam, didn’t you just finish telling Jeffery not to give up??? The real “know it all” guys can’t reply to every message on the forum! Note that Lance didn’t get into the discussion until post-number 11. If you say something wrong some one will be bound to fix it (“programmer-ic” nature) and at that point both you and the person you where trying to help has learned something. I for one can’t count the number of times I’ve said something stupid around here, but I have learned a lot more than I would have otherwise with many thanks to those who have corrected me.
Of course I might be wrong about all this as well, in which case I’ll probably lose my posting privileges any moment nowI’ll let you know if that happens.
Colin Schmidt
------------------
Colin Schmidt & James Duffy, Praxis Enterprises, Canada
Leave a comment:
-
Guest repliedWell, having a big heart - I think sometimes my desire to help someone overrides using common sense. Of course, Lance is right about adding a button to it. At least it gives you some examples of changing colors on ddt labels and dialogs, if nothing else. Actually Lance, it might be better if you deleted that last post. I think I will gracefully bow out of this thread since I think I will let discretion be the better part of valor and let the guys who really know what they are talking about "do the talking".
My apologies,
Adam
------------------
Leave a comment:
-
If you edit the line:
hBrush = CreateSolidBrush(GetSysColor(%COLOR_BTNTEXT))
to become:
hBrush = CreateSolidBrush(GetSysColor(%COLOR_BTNTEXT + 1))
...then the labels will take up the color of buttons. The +1 is required as a result of a decision MS made back in the Windows 3.0 days and carried forward to continue compatibility! (duh!)
However, this little 'demo' only works until you add a button to the dialog - if this button receives focus all keyboard messages are routed to the button's window procedure which means you need to subclass this also. With the addition of a single button, the button will never lose focus and your interface design (as the "demo" code stands) will cease working.
Bypassing the standard windows keyboard interface behavior creates all sorts of problems that have to be handled by your own code. If you stick with the standard interface behavior then you do not need to spend hours trying to fluff about to get the design exactly as you require.
------------------
Lance
PowerBASIC Support
mailto:[email protected][email protected]</A>
Leave a comment:
-
Adam, Thank you very much for the code. If you use #include "win32api.inc", you don't need #include "ddt.inc". What about push buttons? Jeffrey.
------------------
Leave a comment:
-
Guest repliedDeleted!
[This message has been edited by Adam Ritchie (edited April 08, 2000).]
Leave a comment:
-
Adam, My E-Mail address is 70033,[email protected] I wish that I can scan the whole "Programming Windows Fifth Edition" book into my brain. I checked out "WIN32 Programming" book on the publisher's web site and I am not sure about buying it. Jeffrey.
------------------
Leave a comment:
-
Guest repliedDeleted!
[This message has been edited by Adam Ritchie (edited April 08, 2000).]
Leave a comment:
-
Semen, I gave up on the project. I wrote a version of my program that uses WIN32API calls to create dialogs and controls. I am thinking of using PB/DLL to enhance Visual BASIC programs. Jeffrey.
------------------
Leave a comment:
-
Lance, I gave up on the project. I am thinking of using PB/DLL to enhance Visual BASIC programs. I tried to log into this web site at about 7:30 AM Eastern Time but I got a message saying that the site was not found. Jeffrey.
------------------
Leave a comment:
-
Adam, I gave up on the project because I can't get PB/DLL programs with DDT controls to process keystrokes. Lance told me that I have to use WIN32API to create dialogs and controls that process keystrokes. I am thinking of using PB/DLL to enhance Visual BASIC programs. Jeffrey.
------------------
Leave a comment:
-
Jeffrey
In my sample
1) IsTrue(GetWindowLong(GetDlgItem(CbHndl, 102), %GWL_STYLE) And %WS_DISABLED) - means DISABLED
and is equal
IsFalse(IsWindowEnabled(GetWindowLong(GetDlgItem(CbHndl, 102))))
IsFalse(GetWindowLong(GetDlgItem(CbHndl, 102), %GWL_STYLE) And %WS_DISABLED) - means ENABLED
and is equal
IsWindowEnabled(GetWindowLong(GetDlgItem(CbHndl, 102)))
There is a lot of "duplicate" functions in API.
IsWindowEnabled - sure - tests the same bit in GWL_STYLE.
2) I remember your big code.
Try to describe your task by words, perhaps, we'll offer better interface.
I write programs, which calculates railway's tariff for cargoes.
Network has about 9000 stations.
Customers type "Departure", "Destination" and - only if they what to change "default" way - one or some "via" stations.
For example, "default way" from west part of Russia to Turkmenia is through Kazakhstan (by land), but customers could be interesting to use Azerbaidjan-Turkmenian ferry.
It seems to me that you need something the same.
Much comfortable to make Departure/Destination/Via fields as Listbox, not Textbox.
------------------
Leave a comment:
-
Jeffrey, there should be no need to use PostQuitMessage() with DDT... use the DIALOG END CBHNDL statement instead, which causes your code to continue on from the DIALOG SHOW MODAL statement. From that point you can drop out of PBMAIN or whatever action is necessary. Using PostQuitMessage() will cause a conventional message-loop to fall-through, but your dialog is not destroyed until app termnination occurs. While PostQuitMessage() may 'work', it's not the most ideal way to terminate a dialog-based application.
Also please note that %WM_CHAR is not a message that is sent to a DDT dialog callback. To capture %WM_CHAR you need to use Semen's 'experimental' message-loop code with a MODELESS dialog, as you and Semen have discussed in another thread here.
To summarize: When a keystroke is processed by a message loop, the TranslateMessage() converts %WM_KEYDOWN/%WM_KEYUP messages into %WM_CHAR and then DispatchMessage() send that message to the control with focus if there is one - if there is no control with focus, then Windows "swallows" the message and beeps at you to tell you the keypress was "lost or invalid".
This means that a %WM_CHAR messages are only going to be received by controls' window procedures (ie, Windows itself), which in turn *may* process such messages and dispatch a consequential message to [your] button callback (ie, %BN_CLICKED, etc). In other words, raw keyboard messages go everywhere except to your callback. To grab these messages (without snatching them in the message loop), you have to subclass each and every control on your dialog, and as noted above, only if one of these controls has focus.
If we compare this behavior with what VB presents, you'll get some idea of what hoops VB has to go through, and hence why it creates slow/bloated applications, with little regard to whether you want to use such features a "key preview". Conversely, PB has no such manditory overhead, which means you have to get "down and dirty" with the API. These techniques are necessary because of the way Windows actually works at the API level - VB hides most of this from you because it uses a collection of custom controls (superclassed standard controls) so that VB can manipulate messages into it object properties and methods.
Finally, for the type of application you are writing (where you want to be able to use the keyboard interface in a non-standard way), you may just be better off writing the application as a 'standard window' based app (use CreateWindow(), etc), rather than by using a dialog. You can certainly get the job done either way with PB - it's just a matter of how you want to write the code.
------------------
Lance
PowerBASIC Support
mailto:[email protected][email protected]</A>
Leave a comment:
Leave a comment: