0

I have multiple checkboxes. CTRL[], ALT[], SHIFT[]. Is it possible to add modifier if checkobx is checked?

RegisterHotKey(_hWnd, 2, (uint)fsModifiers.None, (uint)LSettings.Key_ON);

Example of what i want to achieve: If checkbox CTRL[X] and ALT[X] are checked:

RegisterHotKey(_hWnd, 2, (uint)fsModifiers.Control | (uint)fsModifiers.Alt, (uint)Keys.S);

I know i can use 7 IFs, but this it would be very messy, since user will be able to check if he wants to use ctrl and or alt and or shift and or key,. I even tried with some arrays, but no idea how to solve this.

JayJay
  • 70
  • 1
  • 9
  • What's the error you're getting? how is `fsModifiers` defined? – MarcinJuraszek May 18 '14 at 00:07
  • You need to unregister the old hot key before creating a new one with the same ID. (At least on modern versions of Windows. I'm assuming you're using 7 or 8.) – Cody Gray - on strike May 18 '14 at 00:45
  • Unregistering old hotkeys isn't a problem. I want to know how to create array or just how to do it without using 7x IFs. I don't get ny erros, how could i, 2nd code is just an example of what i would like to achieve. – JayJay May 18 '14 at 00:47
  • @Capa, do i understand correctly that your problem is how to create OR-combinations of *fsModifiers* enum values programmatically (based on the state of checkboxes)? –  May 18 '14 at 00:57

2 Answers2

1

Avoid making the code needlessly complicated. Just do it like this:

RegisterHotKey(_hWnd,
               2,
               (chkCtrl.Checked     ? fsModifiers.Ctrl  : 0)
                | (chkAlt.Checked   ? fsModifiers.Alt   : 0)
                | (chkShift.Checked ? fsModifiers.Shift : 0)
                | (chkWin.Checked   ? fsModifiers.Win   : 0),
               (uint)Keys.S);

where chkCtrl, etc. are the names of your checkbox controls.

I don't know why you're casting each fsModifiers value to uint. I have removed those casts from my code. If you want to ensure that you pass a uint value, then just declare the enumeration that way:

enum fsModifiers : uint
{
   Alt      = 0x0001,
   Ctrl     = 0x0002,
   Shift    = 0x0004,
   Win      = 0x0008,
   NoRepeat = 0x4000,
};

Yes, this way you do effectively have 4 "IF" statements. The conditional operators will likely compile down to exactly the same IL as if you had written "IF" statements. But, in this case, they are easier to read.

There's not going to be any real performance advantage to finding some complicated way of rewriting this logic with bit arrays. The bottleneck will not be the logic to compute the parameters to pass to the RegisterHotKey function, it will be the actual call to the RegisterHotKey function. There is no way for either the compiler or the JIT compiler to optimize this, you're P/Invoking an external function located in a system DLL. That's slow (relatively speaking, of course; it is still not a performance problem in an application).

And personally, I think there would be a readability (and therefore maintenance) cost to making the logic more complicated. With the code above, anyone with basic programming knowledge can figure out what is happening.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • Thanks for reply. This is an excellent solution, but still i have an issue with the code. **Operator | cannot be applied to operands of type int and bool**. chkCtrl.Checked ? fsModifiers.Ctrl : 0 | chkAlt.Checked ? fsModifiers.Alt : 0 | chkShift.Checked ? fsModifiers.Shift : 0 | chkWin.Checked ? fsModifiers.Win : 0, – JayJay May 19 '14 at 08:18
  • Ok it works i need to add (()): ((cbox.cbTOGGLE_ON_CTRL.Checked ? (uint)fsModifiers.Control : (uint)fsModifiers.None) | (cbox.cbTOGGLE_ON_CTRL.Checked ? (uint)fsModifiers.Control : (uint)fsModifiers.None)), (uint)Keys.S); – JayJay May 19 '14 at 08:21
  • Yeah, always good to add parentheses. You miss little things like that when you don't try to compile the code first. Obviously I don't have the operator associativity rules memorized. Updated my answer. – Cody Gray - on strike May 19 '14 at 12:47
0

If it's the multiple or problem, you might try the following:

Dim Dipswitch as boolean() 'a single array of boolean
If DipSwitch(0) Then DoA
If DipSwitch(1) Then DoB
If DipSwitch(2) Then DoC
If DipSwitch(3) And Not DipSwitch(4) Then DoD

etc. A tag could then be something like "0011". For the situation of Dipswitch 3 and 4 Hope I understood your question well.

Oldskool
  • 34,211
  • 7
  • 53
  • 66
  • Thanks for reply, but i'm not that advenced in c#. I will read about this and try to figure this out on my own, i Will mark answer as solved if i will be able to use it. – JayJay May 18 '14 at 10:15