|
Hi all
Is it possible to get the name of a key on the keyboard but only knowing the virtual-key code? I know you can store all the key names and use it as a list to get the name. But isn’t it possible to get it from a windows API? I also know that you can use the GeyKeyNameText API function but that requires an lParam parameter with keystroke information but isn’t it possible to fake an lParam message and use it in GeyKeyNameText? Or are there other methods or functions of getting the key name from a virtual-key code?
Aidman » over and out
|
|
|
|
|
You are probably looking to function GetKeyNameText Function [^]
To use it, virtual-key codes have to be converted using MapVirtualKeyEx .
HTH,
K.
Angels banished from heaven have no choice but to become demons
Cowboy Bebop
|
|
|
|
|
Yes, but the GetKeyNameText function needs a lParam parameter and where the ScanCode is in a bitfeild. How do I place the Scancode (that is converted from the virtual-keycode) in a bitfeild?
Aidman » over and out
|
|
|
|
|
Here's the way to do it:
Let's suppose you want to convert the virtual key nVirtKey (UINT)
#define BUFFER_LEN 50<br />
TCHAR szBuffer [BUFFER_LEN + 1];<br />
<br />
UINT nScanCode = ::MapVirtualKeyEx (nVirtKey, 0, ::GetKeyboardLayout (0)) <<16 | 0x1;<br />
<br />
if (nVirtKey >= VK_PRIOR && nVirtKey <= VK_HELP){<br />
nScanCode |= 0x01000000;<br />
}<br />
<br />
HTH,<br />
<br />
K.<br />
::GetKeyNameText (nScanCode, szBuffer, BUFFER_LEN);
Angels banished from heaven have no choice but to become demons
Cowboy Bebop
|
|
|
|
|
Thanks this works, but I can oneastly say I have no idea how it all works
Sorry, but could you explain exactly what the "<<16 | 0x1;" and "nScanCode |= 0x01000000;" part does?
Aidman » over and out
|
|
|
|
|
The GeyKeyNameText takes as first parameter lParam.
MSDN says:
lParam
[in] Specifies the second parameter of the keyboard message (such as WM_KEYDOWN) to be processed. The function interprets the following portions of lParam.
Bits Meaning
16–23 Scan code.
24 Extended-key flag. Distinguishes some keys on an enhanced keyboard.
25 "Don't care" bit. The application calling this function sets this bit to indicate that the function should not distinguish between left and right CTRL and SHIFT keys, for example.
the operation <<16 (shifting 16 bits to the left) sets the bits 16 to 23. The operation |= 0x01000000 sets the extendey key flag, the bit 24.
If you look in MSDN to the description of WM_KEYDOWN, you'll see that the bits 0 to 15 are used to set the repeat count. Here it's done with the |0x1
This last operation is probably useless, 'cause it should not be interpreted by GetKeyNameText.
HTH,
K.
Angels banished from heaven have no choice but to become demons
Cowboy Bebop
|
|
|
|
|
Ok thank you for you help it is great, I think I got parts of it figuerd. But I don't completly understand the bit shifting operation and the "|=" operation. Do you know any other good examples or articales/tutorials on this type of operations? And what is this type of operations called?
Aidman » over and out
|
|
|
|
|
These operators are standard C operators. You should find all the info about them in MSDN
(note: a |= b <=> a = a | b , as i += j <=> i = i + j )
Angels banished from heaven have no choice but to become demons
Cowboy Bebop
|
|
|
|
|
Hello, I'm making some changes to a Win32 app that is programmed in standard C (meaning no MFC). I'd like to handle the WM_NCHITTEST in a Dialog Box procedure, but am not sure how to indicate to the OS a result code I'd normally send back in a standard WindowProc.
For example, in a standard WndProc, you return an LRESULT. So, if I wanted to let's say add a sizing grip to the lower right corner of a window, I would need to do something like this:
case WM_NCHITTEST:
if (Mouse Cursor is in lower right 16x16 rectangle of window)
return HTBOTTOMRIGHT;
else
DefWindowProc(etc...);
How does one handle this message properly in a Dialog Proc though, since you can't return an LRESULT?
Thanks,
-Sil
|
|
|
|
|
|
Nish, worked like a champ. Thanks much!
-Sil
|
|
|
|
|
Hi
I'm a beginner in VC.
I created a CObject-derived class (CGraphPlotter below).One of its functions create an CFrameWnd object, draw something and then try to display it on the frame.Below is the extract..
But it runs into exception error and i think the problem lies with ShowWindow().I don't know what to do.Invalidate doesnt work too.Can anyone help?Thks.
void CGraphPlotter::CreatePlot(CString title)<br />
{<br />
RECT rect;<br />
POINT pt;<br />
RECT windowSize;<br />
<br />
CFrameWnd *pwndPlot = new CFrameWnd;<br />
<br />
windowSize.left = 0;<br />
windowSize.top = 0;<br />
windowSize.bottom = 300;<br />
windowSize.right = 600;<br />
<br />
pwndPlot->Create(NULL,title,WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,windowSize,NULL,NULL,0,NULL);<br />
<br />
pwndPlot->GetClientRect(&rect);<br />
pt.x=rect.right;<br />
pt.y=rect.bottom;<br />
<br />
CPaintDC dc(pwndPlot);<br />
CPen plotPen;<br />
CPen *pOldPen;<br />
POINT pt;<br />
<br />
plotPen.CreatePen(PS_SOLID,0,RGB(200,0,0));<br />
pOldPen=dc.SelectObject(&plotPen);<br />
<br />
double m_sampleData[5];<br />
int m_sampleXAxis[5];<br />
<br />
dc.MoveTo(0,0);<br />
for(int i=0;i<4;i++)<br />
{<br />
pt.x=m_sampleXAxis[i];<br />
pt.y = m_sampleData[i];<br />
dc.LineTo(pt);<br />
}<br />
<br />
pwndPlot->ShowWindow(SW_SHOW);<br />
}
|
|
|
|
|
you have to write the painting code in OnDraw.
If you write before, the next time the window paints, whatever you did will get erased.
To do that, you have to create a class CPlotterWnd derived from CFrameWnd and override the OnDraw... although drawing in a frame window is not eh correct way. Framewindow is used to host other windows like views, which inturn display the data.
If you have access to MSDN, it explains it quite well. .. or you have to get a book on MFC.
My article on a reference-counted smart pointer that supports polymorphic objects and raw pointers
modified 29-Aug-18 21:01pm.
|
|
|
|
|
I've gone and read up on MSDN.I understood the concept much better and i hope to use the correct way.
My application is a SDI and i want to display a graph in the CPlotterWnd(CFrameWnd-derived). Am i right to interpret that i should probably derive CGraphPlotter from CView instead? And to associate them together, can i CREATE CPlotterWnd in CGraphPlotter?
thks
|
|
|
|
|
yes. you are better off creating a view for that. If that is the only view that you want, implement your graph plotting in the default view. But, if you want multiple views that look different from the same data, you can create multiple view classes. MSDN has some doumentation on using multiple view types with SDI applications.
Or you can create another view class, host it inside another frame derived class... and create the framewindow, when you click a menu item or a toolbar button. This way, you can create multiple windows showing the same data in different display formats. But, read up on the multiple view handling on SDI before you go out and implement it this way.
My article on a reference-counted smart pointer that supports polymorphic objects and raw pointers
modified 29-Aug-18 21:01pm.
|
|
|
|
|
I have a huge memory leak. I have found that the offending line of code is this one. I comment this part and the leak goes away. The leak is big enough for Windows to say that it is low on virtual memory on a 512 MB machine! m_hdr is a class derived from CHeaderCtrl. There is an image list associated with the header control that has 7 images. The variable direction can be only 0 or 1.
Not being particularly great at MFC UI controls, I copied this from MFC, except for the part where I derive the image index.
HDITEM curItem;<br />
m_hdr.GetItem(column, &curItem);<br />
curItem.mask= HDI_IMAGE | HDI_FORMAT;<br />
curItem.iImage = (sortindex > 3) ? 0 : ((sortindex * 2 + direction) + 1) ;<br />
curItem.fmt= HDF_LEFT | HDF_IMAGE | HDF_STRING;<br />
m_hdr.SetItem(column, &curItem);
My article on a reference-counted smart pointer that supports polymorphic objects and raw pointers
modified 29-Aug-18 21:01pm.
|
|
|
|
|
|
You need to set the mask member of the HDITEM struct before calling GetItem() , so the control knows what info you're asking for. As it is, mask is random data and who knows what the control is putting in the struct.
--Mike--
The Internet is a place where absolutely nothing happens.
-- Strong Bad
1ClickPicGrabber - Grab & organize pictures from your favorite web pages, with 1 click!
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
|
Hello,
I've to add large strings with very different styles to richedit.
how can i add them all to rich edit and then show all in a second ??!
Because it makes filickers when i add each string to richedit !
Regards,
My month article: Game programming by DirectX by Lan Mader.
Please visit in: www.geocities.com/hadi_rezaie/index.html
Hadi Rezaie
|
|
|
|
|
In my old project I added a class CsortListCtrl derived from CListCtrl, and when I #included it (I think thats all I did) when I put a listctrl on the dialog and used the CW to make a variable for it, it gave me two choices for the type of the control: SO I could either make it CListCTrl or CSortListCtrl. In this new project I've put the control on the form, #included it, but the CW is only offering me one choice i.e. it can only be of type CListCtrl. WHat to do? I need
CSortLIstCTrl mySortCTrl;
|
|
|
|
|
Hiya getting a message saying "Database error - There were no columns specified to retrive." when using these 2 lines:
SqlString = "DELETE * from Branches WHERE Branch_No LIKE '4%' ";
OR
SqlString = "INSERT INTO Branches (Branch_No,Branch_Name) VALUES ('6','Derry') ";
But Branch_No is the first column and Branch_Name is the second..
Am I using the statements wrong??
Thanks,
grahamoj.
|
|
|
|
|
grahamoj wrote:
SqlString = "DELETE * from Branches WHERE Branch_No LIKE '4%' ";
It should be DELETE FROM <table_name> WHERE <condition>
Vini
|
|
|
|
|
grahamoj wrote:
SqlString = "INSERT INTO Branches (Branch_No,Branch_Name) VALUES ('6','Derry') ";
1. What is the error message
2. Does the row exists, if so the statement will fail
3. Is Branch_No declared as INT it so try 6 not '6', although I don't think this will make any diference.
If I have seen further it is by standing on the shoulders of Giants. - Isaac Newton 1676
|
|
|
|
|
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the recordset
CRecordset recset( &database );
// Build the SQL statement
SqlString = "DELETE FROM Branches WHERE Branch_No LIKE '4%'";
//SqlString = "INSERT INTO Branches (Branch_No,Branch_Name) VALUES ('6','Derry') ";
// Execute the query
recset.Open( CRecordset::forwardOnly,SqlString,CRecordset::readOnly );
I now know it is the last line, so changed it to:
recset.Open( AFX_DB_USE_DEFAULT_TYPE,SqlString,CRecordset::none );
but this still does not delete the line. The error message I am getting is:
"Database Error: Attempt to open a table failed - there were no columns to retrive were specified".
But my table is called Branches and is specified!!
Any ideas.
grahamoj
|
|
|
|