Why is the dwControlKeyState of the pressed key does not match constant? - c++

I'm trying to handle the keypress event of the console in Windows 7.
When I'm press a left ctrl key i'm expecting to get code 0x0008 (0b00001000 - LEFT_CTRL_PRESSED), but instead of this i'm getting 0x0028 (0b00101000).
...
DWORD n;
INPUT_RECORD ir;
HANDLE hin;
hin = GetStdHandler(STD_INPUT_HANDLE);
...
ReadConsoleInput(hin, &ir, 1, &n)...
...
if(ir.Event.KeyEvent.dwControlKeyState == LEFT_CTRL_PRESSED) {
// some code..
}
if using xor 32 all works fine:
if((ir.Event.KeyEvent.dwControlKeyState ^ 32) == LEFT_CTRL_PRESSED) {
// some code..
}
Where did the extra bits?
p.s.: project in unicode

dwControlKeyState is a bitmap.
The single bits of the dwControlKeyState describe the states of certain keys at the same time.
The 3rd (0-indexed) bit equals 0x008 and indicates left-ctrl-key pressed.
To test for it do like so:
if (ir.Event.KeyEvent.dwControlKeyState & LEFT_CTRL_PRESSED) {
// some code..
}
For a full description of this bitmap you might like to read here under dwControlKeyState: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684166%28v=vs.85%29.aspx

If you want to check if LEFT_CTRL_PRESSED is active, you should use
if (ir.Event.KeyEvent.dwControlKeyState & LEFT_CTRL_PRESSED)
as dwControlKeyState contains several bits indicating different things. Your ^ 32 will invert the value of the NUMLOCK_ON bit, so if you press num-lock, your code will suddenly change behaviour - which is probably not what you want to do.

Related

Function gets called multiple times

So, inside the game loop function that tracks user input is called multiple times. I guess this happens because game loop goes like 40 iterations each second and if I hold down the key for a 0.5 second, function gets called 20 times. I tried to handle this with sfml events too but it didn't work window.setKeyRepeatEnabled(false). How can I solve this?
//this gets called 20-30times
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
leftPlayerPoints++;
}
Use two boolean flags: One for checking if the key is pressed or not, and one that is used to check if the action have happened yet.
In short something like
if (key_is_pressed)
{
if (!action_have_happened)
{
// Perform action...
action_have_happened = true;
}
// Else: Action have already happened this key-press, don't do it again
}
When the key is released reset both flags (to false).
That's what exactly IsKeyPressed is suppose to do , you have to use bitmasking and make it toggle state instead of continuing pressing.
Below is code from Win32API (C++). I know SFML has different events than Win32API but Masking should work in SFML also.
BOOL IsKeyToggled(CONST INT key)
{
SHORT key_state = GetAsyncKeyState(key);
BOOL is_toggled = key_state & 0x1;
return is_toggled;
}
The main point here is key_state & 0x1; bit masking with 0x1

Timer1 acting weird on Arduino UNO (ATMEGA328)

I am trying to implement a simple timer1 example that I saw on YouTube: http://youtu.be/Tj6xGtwOlB4?t=22m7s . The example was in c++ for stand alone ATMEGA328 chip and I am trying to get it to work on the Arduino UNO. Here is my working code:
void setup() {
//initialize port for LED
DDRB = 0b11111111; //initialize port B as output (really only care about 5th bit)
PORTB = 0b00000000; //set ouput values to zero
TCCR1A = 0; //clear control register A (not sure that I need this)
TCCR1B |= 1<<CS10; //no prescaler, turns on CS10 bit of TCCR1B
}
void loop() {
if (TCNT1 >= 255){
TCNT1 = 0; //resets timer to zero
PORTB ^=1<<PINB5; //1<<PINB5 is same as 0b00100000, so this toggles bit five of port b which is pin 13 (red led) on Arduino
}
}
Everything is working, but TCNT1 will only count up to 255. If I set the value in the if-statement to anything higher, the code in the if statement is never executed. Timer1 should be a 16-bit timer, so it does not make sense why the count stops at 255. Is arduino doing something behind the scenes to mess this up? It seems to work just fine in the example on youtube (without arduino).
First of all.... Why do you set the registers? Arduino's only benefit is that it wraps up some functions, so why not use it? Instead of
DDRB = 0b11111111;
PORTB = 0b00000000;
...
PORTB ^=1<<PINB5;
use simply
int myoutpin = XXXX; // Put here the number of the ARDUINO pin you want to use as output
...
pinMode(myoutpin, OUTPUT);
...
digitalWrite(myoutpin, !digitalRead(myoutpin));
I think that probably there are some similar functions for the timer too..
As for your question, I tried this code:
// the setup routine runs once when you press reset:
void setup() {
TCCR1A = 0; //clear control register A (not sure that I need this)
TCCR1B |= 1<<CS10; //no prescaler, turns on CS10 bit of TCCR1B
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
if (TCNT1 >= 12000){
TCNT1 = 0; //resets timer to zero
Serial.println("Timer hit");
}
}
in a simulator and it works well; I should try it with a real Arduino, but I haven't any at the moment... As soon as i get one I'll try to use it
I've encountered the same problem, in the Atmel documentation, I found that other pins influence the counter mode. That is, the pins: WGM13,WGM12,WGM11,WGM10 are 0,1,0,0 respectively, the counter will be in CTC mode, meaning that it will count up to the value of OCR1A instead of (2^16-1) which might be the case in your code.
WGM11,WGM10 are bits 1,0 in TCCR1A and WGM13,WGM12 are bits 4,3 in TCCR1B so setting them to zero should do the job.
I had some thing like this with one of my code. I could not able to find the exact reason for the issue. At last I remove both setup and loop function an replace those with c code.
Then it work fine. If you need those function then start code by clear both TCCR1A and TCCR1B register. I hope this is happened due to Arduino IDE not sure. But it works.

psmouse driver inverse mouse

I just wanna have fun with the mouse driver under Ubuntu Linux. I have got the psmouse-base.c and I can compile it and load it to a kernel as well. The only thing which I want to do is to inverse the mouse. I have found this function which receives the data from the mouse
psmouse_interrupt(struct serio *serio,unsigned char data, unsigned int flags)
where the received data is stored in the unsigned char data. I figured it out that 6 data represents every possible mouse state so it receives 6 data and after 6 again but I cannot figure it out what does these data stand for. If somebody could tell me the answer or tell me where to find a documentation which describes it I would be happy.
I think I have found something. Since I use touch pad I keep receiving 6 byte. I found the description of the data here: www.synaptics.com/sites/default/files/511-000024-01a.pdf. It can be found at the 2nd and the 3rd page. According to this documentation the direction of the movement can be found in the 4th byte's 4th and 5th bits. But the following code does nothing:
if (psmouse->pktcnt == 3)
{
data |= 1 << 4;
data |= 1 << 5;
}
I would assume that I could only move my mouse only in one direction in the x and the y axes.
I have found out that the driver which is responsible for my touch pad is elentech.c.
x1 = ((packet[1] & 0x0f) << 8) | packet[2];
y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
And these lines calculates the movement. I could reverse my touch pad in the x axes but it was just a luck. I have no idea why it works. The following line does it:
psmouse->packet[1] *=-1;
psmouse->packet[2] *=-1;
However I would assume that the next lines do the same thing that the previous two but they don't:
psmouse->packet[1] ^= 0x80;
psmouse->packet[2] ^= 0x80;
And I wasnt able to inverse the mouse in the y axes. Any idea?
You are probably better off modifying the code that handles the packet, psmouse_process_byte, rather than the interrupt handler itself.
It reports the X&Y movements here, and it shouldn't be very hard to make it move the other way around.
Basically, all you need to do is reverse the XNG/YNG bits (packet[0] bits 4 & 5 respectively).
Here's one page that describes the packet format:
http://www.computer-engineering.org/ps2mouse/
Another here:
http://wiki.osdev.org/Mouse_Input

My interrupt routine does not access an array correctly

Update to this - seems like there are some issues with trig functions in math.h (using MPIDE compiler)- it is no wonder I couldn't see this with my debugger which was using its own math.h and therefore giving me the expected (correct solutions). I found this out by accident on the microchip boards and instead implemented a 'fast sine/cosine' algorithm instead (see devmaster dot com for this). My ISR and ColourWheel array now work perfectly.
I must say that, as a fairly newcomer to C/C++ I have spent a lot of hours reviewing and re-reviewing my own code for errors. The last possible thing on my mind was that some very basic functions that were no doubt written decades ago could give such problems.
I suppose I would have seen the problem earlier myself if I'd had access to a screen dump of the actual array but, as my chip is connected to my led cube I've no way to access the data in the chip directly.
Hey, ho !! - when I get the chance I'll post a link to a u tube video showing the wave function that I've now been able to program and looks pretty good on my LED cube.
Russell
ps
Thank you all so very much for your help here - it stopped me giving up completely by giving me some avenues to chase down - certainly did not know much about endianess before this so learned about that and some systematic ways to go about a robust debugging approach.
I have a problem when trying to access an array in an interrupt routine.
The following is a snippet of code from inside the ISroutine.
if (CubeStatusArray[x][y][Layer]){
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
if((ColourWheel[Colour]>>16)&(1<<bitpos)) { // This line seems to cause trouble
setHigh(SINRED_PORT,SINRED_PIN);
}
else {
setLow(SINRED_PORT,SINRED_PIN);
}
}
}
..........
ColourWheel[Colour] has been declared as follows at the start of my program (outside any function)
static volatile uint32_t ColourWheel[255]; //this is the array from which
//the colours can be obtained -
//all set as 3 eight bit numbers
//using up 24 bits of a 32bit
//unsigned int.
What this snippet of code is doing is taking each bit of an eight bit segment of the code and setting the port/pin high or low accordingly with MSB first (I then have some other code which updates a TLC5940 IC LED driver chip for each high/low on the pin and the code goes on to take the green and blue 8 bits in a similar way).
This does not work and my colours output to my LEDs behave incorrectly.
However, if I change the code as follows then the routine works
if (CubeStatusArray[x][y][Layer]){
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
if(0b00000000111111111110101010111110>>16)&(1<<bitpos)) { // This line seems to cause trouble
setHigh(SINRED_PORT,SINRED_PIN);}
else {
setLow(SINRED_PORT,SINRED_PIN);
}
}
}
..........
(the actual binary number in the line is irrelevant (the first 8 bits are always zero, the next 8 bits represent a red colour, the next a blue colour etc)
So why does the ISR work with the fixed number but not if I try to use a number held in an array.??
Following is the actual code showing the full RGB update:
if (CubeStatusArray[x][y][Layer]){
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
{if((ColourWheel[Colour]>>16)&(1<<bitpos))
{setHigh(SINRED_PORT,SINRED_PIN);}
else
{setLow(SINRED_PORT,SINRED_PIN);}}
{if((ColourWheel[Colour]>>8)&(1<<bitpos))
{setHigh(SINGREEN_PORT,SINGREEN_PIN);}
else
{setLow(SINGREEN_PORT,SINGREEN_PIN);}}
{if((ColourWheel[Colour])&(1<<bitpos))
{setHigh(SINBLUE_PORT,SINBLUE_PIN);}
else
{setLow(SINBLUE_PORT,SINBLUE_PIN);}}
pulse(SCLK_PORT, SCLK_PIN);
pulse(GSCLK_PORT, GSCLK_PIN);
Data_Counter++;
GSCLK_Counter++; }
I assume the missing ( after if is a typo.
The indicated research technique, in the absence of a debugger, is:
Confirm one more time that test if( ( 0b00000000111111111110101010111110 >> 16 ) & ( 1 << bitpos ) ) works. Collect (print) the result for each bitpos
Store 0b00000000111111111110101010111110 in element 0 of the array. Repeat with if( ( ColourWheel[0] >> 16 ) & ( 1 << bitpos ) ). Collect results and compare with base case.
Store 0b00000000111111111110101010111110 in all elements of the array. Repeat with if( ( ColourWheel[Colour] >> 16 ) & ( 1 << bitpos ) ) for several different Colour values (assigned manually, though). Collect results and compare with base case.
Store 0b00000000111111111110101010111110 in all elements of the array. Repeat with if( ( ColourWheel[Colour] >> 16 ) & ( 1 << bitpos ) ) with a value for Colour normally assigned. Collect results and compare with base case.
Revert to the original program and retest. Collect results and compare with base case.
Confident that the value in ColourWheel[Colour] is not as expected or unstable. Validate the index range and access once. Code speed enhancement included.
[Edit] If the receiving end does not like the slower signal changes caused by replacing a constant with ColourWheel[Colour]>>16, more effcient code may solve this.
if (CubeStatusArray[x][y][Layer]){
uint32_t value = 0;
uint32_t maskR = 0x800000UL;
uint32_t maskG = 0x8000UL;
uint32_t maskB = 0x80UL;
if ((Colour >= 0) && (Colour < 255)) {
value = ColourWheel[Colour];
}
// All you need to do is shift 'value'
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
{ if( (value & maskR) // set red
}
{ if( (value & maskG) // set green
}
{ if( (value & maskB) // set blue
}
value <<= 1;
}

One control returns contents as single-byte, another as double-byte?

I have 2 CRichEditCtrls. One is part of a dialog template, created automatically. When I call GetSelText on it, the bytes returned are one byte per char, i.e I'll get back char *str={'a','n','d'}. The 2nd control is created dynamically using the Create method, and the data returned calling GetSelText is returned in 2-byte characters: char *str={'a',0,'n',0,'d',0}.
This is making things a real pain... see this topic. One way works with one control, one way works with the other.
I can't even see how two controls (on the same dialog) can have different behavior like this. I don't see a way to tell the one created dynamically what way to work.
How can this be going on? The control created dynamically is the odd one out in our application, so that's the one that needs to be changed...
Here is the code I'm using:
ASSERT(::IsWindow(m_hWnd));
CHARRANGE cr;
cr.cpMin = cr.cpMax = 0;
::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
CString strText;
LPTSTR lpsz=strText.GetBufferSetLength((cr.cpMax - cr.cpMin + 1) * 2);
lpsz[0] = NULL;
long nLen = ::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpsz);
lpsz[nLen] = NULL;
for(long i=0;i<nLen;++i)
{
TRACE("lpsz[%d] (%d bytes) = %d {",i,sizeof(lpsz[i]),lpsz[i]);
char *pc = (char *)&lpsz[i];
for(int j=0;j<sizeof(lpsz[i]);++j)
{
TRACE(" %d(%c)",pc[j],pc[j] ? pc[j] : '#');
}
TRACE("}\n");
}
strText.ReleaseBuffer();
return CString(strText);
The output from my dialog-template control:
lpsz[0] (2 bytes) = 28257 { 97(a) 110(n)}
lpsz[1] (2 bytes) = 100 { 100(d) 0(#)}
lpsz[2] (2 bytes) = 52685 { -51(Í) -51(Í)}
And from my dynamically created control:
lpsz[0] (2 bytes) = 97 { 97(a) 0(#)}
lpsz[1] (2 bytes) = 110 { 110(n) 0(#)}
lpsz[2] (2 bytes) = 100 { 100(d) 0(#)}
Your first richedit ctrl is of class "RichEdit20A"
second one is "RichEdit20W" - wide char
One thing you can do is change the class of your first richeditctrl in RC file to RichEdit20W
So, both gives the value in wide_char's.
See this KB article. This will help
http://support.microsoft.com/kb/261171
Use the IsWindowUnicode() API to find out whether the control is ANSI or Unicode.
Ansi controls return single-byte strings, unicode controls return double-byte strings.
And if you change your resourcefile to use RichEdit20W instead of RichEdit20A, you have to check from time to time to make sure it stays as RichEdit20W!
See here for a detailed recipe why this is necessary.
Note: VS2010 seems to have this bug finally fixed.