Windows raw input api

hi,

im working with a scanner to get barcodes. it is a plug and play device but i want to data process the data myself.

to catch al the data i am using windows raw input api.
when i can a couple of barcodes my calback function is never called. but i dont understand why.

using windows 7 and qt 5.

My code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include "mainwindow.h"
#include <QApplication>

#include <windows.h>
#include <QDebug>

// register Scanner
void InitRawInput(HWND hWnd){

    RAWINPUTDEVICE Rid[1];
    Rid[0].usUsagePage = 0x01;
    Rid[0].usUsage = 0x06;
    Rid[0].dwFlags = RIDEV_INPUTSINK;
    Rid[0].hwndTarget = hWnd;
    if (RegisterRawInputDevices(Rid,1,sizeof(Rid[0])) == false)
        {
        qDebug() << "Registration failed";
        return;
        }
    qDebug() << "Registration updated";
}

/*
 * Function that receives messages from OS
 *
 * LRESULT --> returns a 32-bit number (64 for 64 OS)
 * CALLBACK --> specifies how in assembly parameters will get passed
 * 				and returned from the function
 * HWND --> Handle to the window that is receiving messages from the OS
 * UINT --> Says what type of message is being sent
 * WPARAM/LPARAM --> es. X and Y mouse position
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

    qDebug() << "calback";
    LPBYTE lpb;
    UINT dwSize;
    RAWINPUT *raw;
        switch(msg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
            break;

        case WM_INPUT:
            {

            GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));

            lpb = new BYTE[dwSize];

            if (lpb == NULL)
                return 0;

            if (GetRawInputData((HRAWINPUT)lParam,
                RID_INPUT,
                lpb,
                &dwSize,
                sizeof(RAWINPUTHEADER)) != dwSize)
                {
                qDebug() << "GetRawInputData doesn't return correct siz";
                //OutputDebugStr(TEXT("GetRawInputData doesn't return correct size\n"));
                }

            raw = (RAWINPUT*) lpb;

            qDebug() << "whaa";
            if (raw->header.dwType == RIM_TYPEKEYBOARD)
                {
                if (raw->data.keyboard.Message == WM_KEYDOWN ||
                    raw->data.keyboard.Message == WM_SYSKEYDOWN)
                    {
                        USHORT usKey;
                        usKey = raw->data.keyboard.VKey;
                        CHAR szTest[4];
                        _itoa_s((int)usKey,szTest,4,10);

                        WCHAR str[4];
                        MultiByteToWideChar( 0,0, szTest, 4, str, 4);

//                        SetWindowText(hWnd,szTest);
                       SetWindowText(hWnd,str);
                    }
                }

            delete[] lpb;
            return 0;
            }
        }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

       // TODO: code your application's behavior here.

       UINT nDevices;
       PRAWINPUTDEVICELIST pRawInputDeviceList;

       if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
       {
          qDebug() << "Errors...";
          return 1;
       }

       if ((pRawInputDeviceList = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * nDevices)) == NULL)
       {
          qDebug() << "Initialization failed...";
          return 1;
       }

       int nNoOfDevices = 0;
       if ((nNoOfDevices = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST))) == ((UINT) - 1))
       {
          // Error
          return 1;
       }

       RID_DEVICE_INFO rdi;
       rdi.cbSize = sizeof(RID_DEVICE_INFO);

       for(int i = 0; i < nNoOfDevices; i++)
       {
          UINT size = 256;
          TCHAR tBuffer[256] = {0};
          tBuffer[0] = '\0';
          if(GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, tBuffer, &size) < 0)
          {
             // Error in reading device name
              qDebug() << "error reading device name";
          }

           qDebug() << "Device Name: " << tBuffer;
          //_tprintf(L"Device Name: %s\n", tBuffer);

          UINT cbSize = rdi.cbSize;
          if(GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) < 0)
          {
             // Error in reading information
          }

          if(rdi.dwType == RIM_TYPEMOUSE)
          {
             qDebug() << "ID for Mouse:" << rdi.mouse.dwId;
             qDebug() << "Number of Buttons:" << rdi.mouse.dwNumberOfButtons;
             qDebug() << "Sample rate(Number of data points):" << rdi.mouse.dwSampleRate;
             qDebug() << "**************************";
          }

          if(rdi.dwType == RIM_TYPEKEYBOARD)
          {
             qDebug() << "Keyboard Mode:" << rdi.keyboard.dwKeyboardMode;
             qDebug() << "Number of function keys:" << rdi.keyboard.dwNumberOfFunctionKeys;
             qDebug() << "Number of indicators:" << rdi.keyboard.dwNumberOfIndicators;
             qDebug() << "Number of keys total: " << rdi.keyboard.dwNumberOfKeysTotal;
             qDebug() << "Type of the keyboard: " << rdi.keyboard.dwType;
             qDebug() << "Subtype of the keyboard: " << rdi.keyboard.dwSubType;
             qDebug() << "***********************";
          }

          if(rdi.dwType == RIM_TYPEHID)
          {
             qDebug() << "Vendor Id:" << rdi.hid.dwVendorId;
             qDebug() << "Product Id:" << rdi.hid.dwProductId;
             qDebug() << "Version No:" << rdi.hid.dwVersionNumber;
             qDebug() << "Usage for the device: " << rdi.hid.usUsage;
             qDebug() << "Usage Page for the device: " << rdi.hid.usUsagePage;
             qDebug() << "***********************";
          }
       }

       free(pRawInputDeviceList);

       HWND temper = (HWND)w.effectiveWinId();
       InitRawInput(temper);

//        //Struct to hold windows event messages
//        MSG msg;

//        while (GetMessage(&msg, NULL,0,0))
//        {
//            qDebug() << "testersa";
//            TranslateMessage(&msg);
//            DispatchMessage(&msg);
//        }

//    return msg.wParam;
    return a.exec();
}



Device Name:  0x28fa10 
Keyboard Mode: 1 
Number of function keys: 12 
Number of indicators: 3 
Number of keys total:  101 
Type of the keyboard:  81 
Subtype of the keyboard:  0 
*********************** 
Device Name:  0x28fa10 
Keyboard Mode: 1 
Number of function keys: 12 
Number of indicators: 3 
Number of keys total:  264 
Type of the keyboard:  81 
Subtype of the keyboard:  0 
*********************** 
Device Name:  0x28fa10 
ID for Mouse: 2 
Number of Buttons: 2 
Sample rate(Number of data points): 60 
************************** 
Device Name:  0x28fa10 
ID for Mouse: 256 
Number of Buttons: 8 
Sample rate(Number of data points): 0 
************************** 

// + Scanner
Device Name:  0x28fa10 
Keyboard Mode: 1 
Number of function keys: 12 
Number of indicators: 3 
Number of keys total:  154 
Type of the keyboard:  81 
Subtype of the keyboard:  0 
*********************** 
Device Name:  0x28fa10 
Vendor Id: 1035 
Product Id: 25923 
Version No: 256 
Usage for the device:  1 
Usage Page for the device:  65280 
***********************
Registration updated 
Have you tried uncommenting the messageloop? The DispatchMessage function is probably the one that calls your CALLBACK function WndProc.
1
2
3
4
5
6
7
8
9
10
11
//        //Struct to hold windows event messages
//        MSG msg;

//        while (GetMessage(&msg, NULL,0,0))
//        {
//            qDebug() << "testersa";
//            TranslateMessage(&msg);
//            DispatchMessage(&msg);
//        }

//    return msg.wParam; 
Last edited on
- and i suppose that you use a main() function in Qt instead of a WinMain() function as you would in regular WinAPI?
Last edited on
the message loop is not calling WndProc. it is commented for that reason.

I think that the WndProc function is not going to work under QT.
thejman250 wrote:
- and i suppose that you use a main() function in Qt instead of a WinMain() function as you would in regular WinAPI?


Yes, If you make a QT project - the winmain is provided by QT - and that winmain calls your main function.

----But just taking a normal windows or console project and adding some QT headers to it does not make it a QT project if you see what I mean----.

In the original post - the windows procedure is never going to get called by Windows - I think the original poster is very confused
You should override QCoreApplication::winEventFilter in your Qt application to be able to receive normal windows messages:
http://qt-project.org/doc/qt-4.8/qcoreapplication.html#winEventFilter
@guestgulkan Yes i was really confused.

i have something working now. i am using the function NativeEvent from qt 5 now.

But there is a new problem, i want to catch the data from 1 device and not from both. both are keyboards. but in the message i cant find the device where it originated from.

guestgulkan wrote:
Yes, If you make a QT project - the winmain is provided by QT - and that winmain calls your main function.

----But just taking a normal windows or console project and adding some QT headers to it does not make it a QT project if you see what I mean----.

In the original post - the windows procedure is never going to get called by Windows - I think the original poster is very confused


- Thanks for explaining that, and yes i understand.

- If this were WinAPI, the DispatchMessage() function would result in windows calling the windows procedure as far as i know, but i have no clue about Qt.
Last edited on
You can create Application:QApplication. And then reimplement this function if you want to process window messages msg that are not processed by Qt.

Like This:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
bool Application::winEventFilter(MSG *msg, long *result)
{
    LPARAM lParam = msg->lParam;
    LPBYTE lpb;
    UINT dwSize;
    RAWINPUT *raw;
    if (msg->message == WM_INPUT) {

        GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));

        lpb = new BYTE[dwSize];

        if (lpb == NULL)
            return 0;
        if (GetRawInputData((HRAWINPUT)lParam,
                            RID_INPUT,
                            lpb,
                            &dwSize,
                            sizeof(RAWINPUTHEADER)) != dwSize)
        {
            qDebug() << "GetRawInputData doesn't return correct siz";
            //OutputDebugStr(TEXT("GetRawInputData doesn't return correct size\n"));
        }

        raw = (RAWINPUT*) lpb;
        if (Application::m_deviceId == raw->header.hDevice) {
            if (raw->header.dwType == RIM_TYPEKEYBOARD) {
                if (raw->data.keyboard.Message == WM_KEYDOWN ||
                        raw->data.keyboard.Message == WM_SYSKEYDOWN)
                {
                    USHORT usKey;
                    usKey = raw->data.keyboard.VKey;
                    qDebug() << usKey;
//                    qDebug() << "hDevice" << raw->header.hDevice;
                }

            }
            result = 0;
            msg = 0;
            return true;
        }
        qDebug() << "id" << raw->header.dwType << raw->data.keyboard.VKey;
        delete[] lpb;

    }
    return QApplication::winEventFilter(msg,result);
}


Application::m_deviceId is scanner device id.

But I have a problem .When I return true, the message still pass to the text edit widget. And I don't know why?
If you done,please let me know. ([email protected])
Topic archived. No new replies allowed.