|
Hi,
I've the same problem. I want to write the characters @ and # and I need de (altGr) Key. Some one have solve the problem?
thank you
Gemm
|
|
|
|
|
Hello, I've solved the focus problem. The solution is to catch the WM_MOUSEACTIVATE message and return MA_NOACTIVATE.
Changes in OnscreenKeyboardDlg.cpp:
BEGIN_MESSAGE_MAP(COnscreenKeyboardDlg, CDialog)<br />
...<br />
ON_WM_MOUSEACTIVATE()<br />
END_MESSAGE_MAP()
int COnscreenKeyboardDlg::OnMouseActivate( CWnd* pDesktopWnd, UINT nHitTest, UINT message )<br />
{<br />
return MA_NOACTIVATE;<br />
}
Changes in OnscreenKeyboardDlg.h:
...<br />
afx_msg int OnMouseActivate( CWnd* pDesktopWnd, UINT nHitTest, UINT message );<br />
...<br />
That's all.
|
|
|
|
|
You are a great guy
i wanna thanks to you
|
|
|
|
|
Hi,Im trying to do something similar.I want to design an onscreen keyboard based on a mobile phone keyboard.The first thing I want to over come is when i click a button relating to a letter how do i get it to appear in the editor i have open at the same time?Im programming it in Java and have no knowledge of C++.
|
|
|
|
|
Hello, the keyboard looks pretty good and is working fine but I noticed one problem, and that's just the one where fore I want to use this keyboard.
If I open an inputbox with VbScript I want to use the keyboard. If I start typing the character I hit is placed into the inputbox, if I hit the next character the character in the inputbox is overwritten by the last one.
I only can place one character in the inputbox.
Does anyone knows this problem and knows a solution???
Thnx
|
|
|
|
|
I got the same problem , has anyone resolved this issue?
Thanks
Kadji
Long live Microsoft!
|
|
|
|
|
Is there a reason why this wouldn't work under Win98? I haven't tryed and i do not know if it is working or not, but in the article it says that he did this app because he did not find anything that works under Win2000 (that is why I'm asking - is it going to work in Win98, or it uses something specific only for Win2000).
What parts of the code should be changed to make it work in Win98?
Thanks.
|
|
|
|
|
It works for me, and I use Windows 98.
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
There are many virtual keyboards which have no flashing problem. But they are not freeware. Can any C++ expert help us to give a complete virtual keyboard which will have no flashing problem?
|
|
|
|
|
Can't fix the Bug with IE address bar?
|
|
|
|
|
Well done
Regards,
Brian Dela
|
|
|
|
|
I am trying to create application to run as service and when user hit key like CTRL-F1 or CTRL-F2, I want the service to send keyboard message to windows so that I don't have to type my user/pass everytime I have to log in to softwares at work.
I still have to figure out how to create system wide hook to intercept the key, but your application showed me how to use keybd_event function.
I looked it up on the MSDN and it says I should use SendInput() function instead because keydb_event is superseded.
|
|
|
|
|
It's a long time since this source code is published. Has anyone now solved focus problem? If yes then please update the code. (There are now many virtual keyboard that have no focus problem)
Mahbub
|
|
|
|
|
Here's one go at it:
http://home.worldonline.dk/troels_k/code/keyboard.zip
|
|
|
|
|
The keyboard works fine as far as I can tell with everything except Internet Explorer! If you are trying to type into the Address Bar in IE (5.5) only the last key hit is shown in the edit box. And no keystrokes can get through to any web page. Unfortunatly I need to do a Kiosk type application with a web browser, and I can't figure out how to have an on-screen keyboard for the touchscreen!
Corey Cooper
CoreyC@InnovativeDesign.com
|
|
|
|
|
nklnkln
|
|
|
|
|
I've seen the same problem and also for me it's important to understand how to solve this! I think it's a focus problem... Have you seen the Windows XP virtual keyboard? It seems to works well but the keyboard doesn't seem to be focused on. The focus seems to remain always to the foreground window!
Any suggestions?
|
|
|
|
|
You have to prevent to get the focus. See thread "Focus Problem and Flashing" from 18:59 20 Jan '04.
With this patch the IE works.
|
|
|
|
|
Hi,
I do not find that the "Focus Problem and Flashing" solve the problem that the other application looses focus. It prevents our application to get the focus, but it does not prevent the other application from being deactivated.
The XP keyboard and other works fine without the target application looses focus, and that is very important in some situations.
Please update me on this one, if anyone has found the solution.
OleM
|
|
|
|
|
The following is taken from an email I put together a while ago for someone asking how I solved this problem:
I did solve this problem, but only for my particular app which was an MFCApp, using CHTMLView. I think the methodology I used would apply to other situations. Note however, that this code is very specific for my application, I have not tried to make this reusable or generic, I had a deadline that was looming, and I banged this out.
I was trying to type into a webbrowser object hosted by my own app It failed because the WebBrowser is a com object hosted by the MFC generated window that Windows reports as having the focus. How normal keyboard messages get through, I don't know.
Using Spy++ I found that the window I create (the CHtmlView derived window) has a child, which has a child, which has a child that is the actual WebBrowser object. So since I have a pointer to the window that I created, and knew that was where I wanted all my keystrokes to go, I created the following function (CConfigHtml is derived from CHtmlView):
(the operative portion here is the routine that searches for the window with the Class Name of "Internet Explorer_Server")
Note also there are some lines commented out leftover from debugging that I thought might be useful as comments.
void CConfigHtml::Search4RealBrowserhWnd()
{
try{
TRACE0("===== CConfigHtml::Search4RealBrowserhWnd!\n");
if (m_RealBrowserhWnd == NULL){
char *pbuff;
CString cstr;
m_RealBrowserhWnd = m_hWnd;
bool loop = TRUE;
while(loop) {
m_RealBrowserhWnd = ::FindWindowEx(
m_RealBrowserhWnd, //HWND hwndParent, // handle to parent window
NULL, //HWND hwndChildAfter, // handle to child window
NULL, //"Shell Embedding",//LPCTSTR lpszClass, // class name
NULL //LPCTSTR lpszWindow // window name
);
if (m_RealBrowserhWnd != NULL){
pbuff = cstr.GetBuffer(52);
int ret = ::GetClassName( m_RealBrowserhWnd, pbuff, 50);
cstr.ReleaseBuffer();
if (0 != ret){
// ErrorReportf(">>>>>>>>>>>>>GOT Browser Window Handle %#x = %s",(int)m_RealBrowserhWnd,pbuff);
if (cstr.CompareNoCase("Internet Explorer_Server")==0)
loop = FALSE; // That's it, we are done!
}
else
ErrorReportf("Window %#x has no name returned",(int)m_RealBrowserhWnd);
}
else {
SystemErrorReport("Error: getting Window Handle! ");
loop = FALSE;
}
}
}
}
catch(...){
AfxMessageBox("Exception Thrown Getting the Browser Window Handle!");
m_RealBrowserhWnd = NULL;
}
}
And then my version of ReleaseFocus() will only work with my predefined windows:
bool CConfigDlg::ReleaseFocus()
{
if ((HTMLControl != NULL) && IsWindow(HTMLControl->m_RealBrowserhWnd) ) {
HWND wnd = ::GetForegroundWindow();
if(IsWindow(wnd)) {
if(wnd == HTMLControl->m_RealBrowserhWnd) {
TRACE0("Already forground!");
return TRUE;
}
}
}
else if ((EditWithFocus != NULL) && (IsWindow(EditWithFocus->m_hWnd))){
if (NULL == ::SetFocus(EditWithFocus->m_hWnd))
AfxMessageBox("SetFocus Failed!");
}
else {
TRACE0("None of the Focus Pointers are valid!");
return FALSE;
}
return TRUE;
}
I hope I made this clear enough. Since IE is really just a big ActiveX host, the same routine should work, although I had the advantage of already having a handle to the window I knew was hosting the webbrower object. If you are trying to write to IE, you might combine the two routines so that each time ReleaseFocus() is called, it checks to see if a child window of the window it is about to set the focus to has a name of "Internet Explorer_Server". Again, the main thing is play with Spy++ and find the windows and messages, and go from there.
I hope this helped.
|
|
|
|
|
This is great man thanks ive been trying to manipulate standard input and this is the BEST!
Keep up the good work.
Ryan
|
|
|
|
|
I have learned so much from Mr. Randy More's article!
I have some other problems about the OEM scan code(I wonder if this is the right name)of the keys on the keyboard.
For example, the code '0x61' stands for the key 'a' on the keyboard,what about the code of the combination of 'Alt+a'?
I found on books that the code for 'Ctrl-Break' is 0x03, but that is all I got.
I would like to know what are the OEM scan codes that stand for two key combinations of the keyboard.
Or is this any other way to send such information from my code?
Thanks a lot!
|
|
|
|
|
The scan code will still be '0x61' but there will be a flag set for the Alt key being pressed. I'm pulling this from memory but I remember many a fun evening pulling this apart for a project. Ctrl, Shift, and detecting the difference between NumPad keys is also handled this way.
Petzold's Keyboard example from our Win31 days is a really good way to see how this works. You can also use the Proises (sp?) MFC version that has a similar Keyboard example.
|
|
|
|
|
An alternative to the implementation in this example that used the Keybd_event function may be the SendInput function:
UINT SendInput(
UINT nInputs, // count of input events
LPINPUT pInputs, // array of input events to insert
int cbSize // size of an INPUT structure
);
I like SendInput for simulating Key events since I can stuff the queue in the order I want and just get away with virtual key codes. For example, If I use SendInput to stuff the Keyboard input buffer with the following order of events:
KEY_DOWN event for 0x10 // virtual key code for shift,
KEY_DOWN event for 0x31 // Virtual key code for 0,
KEY_UP event for 0x10
KEY_UP event for 0x31
I end up with the "!" placed in the window with the current focus (and there was much rejoicing). I like this approach a bit better since it maps to the way we humans would enter it on the keyboard and I avoid any higher level thought process, bit twiddling, etc. SendInput uses the INPUT struct which contains a union to structs for keyboard events (ki), mouse events (mi) and hardware events (hi). Hopefully, the hastily typed out code fragment that I am including for my discussion isn't too badly reasoned (long day and brain like mush ...). This fragment assumes you have done the proper prerequisite work to get your environment set up not to choke on SendInput, the associated INPUT struct, and the ki struct ... and hopefully gives you an idea of implementing SendInput versus Keybd_event:
// Purpose: SendKey - Sends key events to the window with the current
// focus.
// Uses: SendInput Declared in winuser.h; Import Library: user32.lib.
// Compatibility: NT 4.0(SP3)or later;Win 98 or later;CE Unsupported
// Args:
// vk = Virtual Keycode for simulated key event,
// shift = vk code for shift or pass 0 if shift is not simulated
// control = vk code for control or pass 0 in no control
// alt = you guessed it ... vk code for alt or pass 0
void Sendkey(int vk, int shift, int control, int alt);
void SendKey(int vk, int shift, int control, int alt)
{
// special key ... the vk code holder for shift,control,or alt.
int spkey;
// A key is either shifted, control or alt. Determine which and
// build the keybuffer to accept to keys for this event.
if (shift || control || alt)
{
if (shift) spkey = shift;
else if (control) spkey = control;
else spkey = alt;
INPUT *buffer = new INPUT[4]; //allocate a buffer
buffer->type = INPUT_KEYBOARD;
buffer->ki.wVk = spkey;
buffer->ki.wScan = 0;
buffer->ki.time = 0;
buffer->ki.dwFlags = 0;
buffer->ki.dwExtraInfo =0;
(buffer+1)->type = INPUT_KEYBOARD;
(buffer+1)->ki.wVk = vk;
(buffer+1)->ki.wScan = 0;
(buffer+1)->ki.time = 0;
(buffer+1)->ki.dwFlags = 0;
(buffer+1)->ki.dwExtraInfo =0;
(buffer+2)->type = INPUT_KEYBOARD;
(buffer+2)->ki.wVk = spkey;
(buffer+2)->ki.wScan = 0;
(buffer+2)->ki.time = 0;
(buffer+2)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+2)->ki.dwExtraInfo = 0;
(buffer+3)->type = INPUT_KEYBOARD;
(buffer+3)->ki.wVk = vk;
(buffer+3)->ki.wScan = 0;
(buffer+3)->ki.time = 0;
(buffer+3)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+3)->ki.dwExtraInfo = 0;
// Here is the Sendinput function implemented
// queue is stuffed with 4 events pointed to by buffer
// with the sizeof an INPUT struct.
SendInput(4,buffer,sizeof(INPUT));
delete (buffer); // We always clean up our messes.
}
// Check for combinations of 2 special keys, i.e. shift-alt,
// ctrl-alt,shift-ctrl by intersecting logical conditions of
// the 3 possible keys that can be pressed at once and building
// the buffer to accept 3 key events.
else if ((shift || control) && (control || alt))
{
INPUT *buffer = new INPUT[6]; //Buffer 3 key events
// Key Presses .. the first 3 events what are the 2 keys modifying
// the third?
// Determine first condition for which key had a value ...
// either shift or control and input the key into the buffer.
if (shift) spkey = shift;
else spkey = control;
buffer->type = INPUT_KEYBOARD;
buffer->ki.wVk = spkey;
buffer->ki.wScan = 0;
buffer->ki.time = 0;
buffer->ki.dwFlags = 0;
buffer->ki.dwExtraInfo =0;
// Determine what the second key is that made the test true
// and put the key into the buffer.
if (alt) spkey = alt;
else spkey = control;
(buffer+1)->type = INPUT_KEYBOARD;
(buffer+1)->ki.wVk = spkey;
(buffer+1)->ki.wScan = 0;
(buffer+1)->ki.time = 0;
(buffer+1)->ki.dwFlags = 0;
(buffer+1)->ki.dwExtraInfo =0;
(buffer+2)->type = INPUT_KEYBOARD;
(buffer+2)->ki.wVk = vk;
(buffer+2)->ki.wScan = 0;
(buffer+2)->ki.time = 0;
(buffer+2)->ki.dwFlags = 0;
(buffer+2)->ki.dwExtraInfo = 0;
(buffer+3)->type = INPUT_KEYBOARD;
(buffer+3)->ki.wVk = buffer->ki.wVk;
(buffer+3)->ki.wScan = 0;
(buffer+3)->ki.time = 0;
(buffer+3)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+3)->ki.dwExtraInfo = 0;
(buffer+4)->type = INPUT_KEYBOARD;
(buffer+4)->ki.wVk = (buffer+1)->ki.wVk;
(buffer+4)->ki.wScan = 0;
(buffer+4)->ki.time = 0;
(buffer+4)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+4)->ki.dwExtraInfo = 0;
(buffer+5)->type = INPUT_KEYBOARD;
(buffer+5)->ki.wVk = vk;
(buffer+5)->ki.wScan = 0;
(buffer+5)->ki.time = 0;
(buffer+5)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+5)->ki.dwExtraInfo = 0;
SendInput(6,buffer,sizeof(INPUT));
delete(buffer);
}
// the dreaded Shift, Control, Alt + Key combination
else if (shift && control && alt)
{
INPUT *buffer = new INPUT[8];
buffer->type = INPUT_KEYBOARD;
buffer->ki.wVk = shift;
buffer->ki.wScan = 0;
buffer->ki.time = 0;
buffer->ki.dwFlags = 0;
buffer->ki.dwExtraInfo =0;
(buffer+1)->type = INPUT_KEYBOARD;
(buffer+1)->ki.wVk = control;
(buffer+1)->ki.wScan = 0;
(buffer+1)->ki.time = 0;
(buffer+1)->ki.dwFlags = 0;
(buffer+1)->ki.dwExtraInfo =0;
(buffer+2)->type = INPUT_KEYBOARD;
(buffer+2)->ki.wVk = alt;
(buffer+2)->ki.wScan = 0;
(buffer+2)->ki.time = 0;
(buffer+2)->ki.dwFlags = 0;
(buffer+2)->ki.dwExtraInfo = 0;
(buffer+3)->type = INPUT_KEYBOARD;
(buffer+3)->ki.wVk = vk;
(buffer+3)->ki.wScan = 0;
(buffer+3)->ki.time = 0;
(buffer+3)->ki.dwFlags = 0;
(buffer+3)->ki.dwExtraInfo = 0;
(buffer+4)->type = INPUT_KEYBOARD;
(buffer+4)->ki.wVk = shift;
(buffer+4)->ki.wScan = 0;
(buffer+4)->ki.time = 0;
(buffer+4)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+4)->ki.dwExtraInfo = 0;
(buffer+5)->type = INPUT_KEYBOARD;
(buffer+5)->ki.wVk = control;
(buffer+5)->ki.wScan = 0;
(buffer+5)->ki.time = 0;
(buffer+5)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+5)->ki.dwExtraInfo = 0;
(buffer+6)->type = INPUT_KEYBOARD;
(buffer+6)->ki.wVk = alt;
(buffer+6)->ki.wScan = 0;
(buffer+6)->ki.time = 0;
(buffer+6)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+6)->ki.dwExtraInfo = 0;
(buffer+7)->type = INPUT_KEYBOARD;
(buffer+7)->ki.wVk = vk;
(buffer+7)->ki.wScan = 0;
(buffer+7)->ki.time = 0;
(buffer+7)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+7)->ki.dwExtraInfo = 0;
SendInput(8,buffer,sizeof(INPUT));
delete(buffer);
}
// simple unmodified normal key event
else
{
INPUT *buffer = new INPUT[2];
buffer->type = INPUT_KEYBOARD;
buffer->ki.wVk = vk;
buffer->ki.wScan = 0;
buffer->ki.time = 0;
buffer->ki.dwFlags = 0;
buffer->ki.dwExtraInfo =0;
(buffer+1)->type = INPUT_KEYBOARD;
(buffer+1)->ki.wVk = vk;
(buffer+1)->ki.wScan = 0;
(buffer+1)->ki.time = 0;
(buffer+1)->ki.dwFlags = KEYEVENTF_KEYUP;
(buffer+1)->ki.dwExtraInfo =0;
SendInput(2,buffer,sizeof(INPUT));
delete(buffer);
}
}
Assuming I don't have typos ... (Big assumption) ... this fragment should hopefully illustrate the use of SendInput. And remember if you are one of our CE friends ... ignore this and stick with the Keybd_event function.
Rich L.
|
|
|
|
|
Have you seen the onscreen keyboard at http://www.virtual-keyboard.com/?
These keyboards run under Windows 95/98/NT, and have no "flashing" problem.
|
|
|
|
|