How applications on Windows receive APP path data from Norwii wireless presenter.

2024-12-18 13:41:09 诺为

Norwii wireless presenter is a USB HID device (Human Interface Device) for computers, just like a mouse and keyboard. The technology used is the same as wireless keyboard and wireless mouse. 

Currently, if you want to get the key information of the wireless presenter on your computer, or if you want to use the wireless presenter to control the software on your computer, there are two ways. One is to customize the key functions of the wireless presenter as the shortcut keys of the application software in the computer, and the application software triggers the corresponding functions by getting the shortcut keys from the USB HIDPath. For this method, please refer to the manual of Norwii Presenter software on the Norwii official website for a more detailed introduction. The other is to customize the data of the APP path of the wireless presenter keys first, and the application software accepts the control by getting the data of the APP path. This article is about how to customize and read the APP path data of the keys of Norwii wireless presenter by the application software on Windows, which is mainly about the program implementation. 

The APP path here refers to a Norwii defined HID Path used to communicate with the APP.

It is possible to customize the short press, long press, and double press of a key as data for the APP path. The short press described in this article is triggered when the key is lifted, if no key is lifted beyond the long press timer, it is a short press. A long press is triggered when a key is held down continuously for more than the long press timer. The long press timer is generally 1 second and may vary for different products or keys. 

I. Using Norwii Presenter software to customize the data of the APP path of the Norwii wireless presenter keys.

1. On the [Customize] tab of the Norwii Presenter software, click on the wireless presenter button icon or the blue text corresponding to this icon displayed on the software interface, and the button customization window will open. There are 3 or 4 button modes for the wireless presenter, which can be switched by pressing and holding the page up and page down buttons of the wireless presenter at the same time, and there are 4 modes in the figure below. Users can choose one of the key modes to customize, and the customized result is only valid in this mode.

Norwii Wireless Presenter

2. Click "drop-down arrow" - "APP Path" in "Short Press Function" to enter the APP Path window, enter one of the decimal number 1~255 as the value of APP Path in the edit box, click "Ok" and then click "Save" in the previous window.

Norwii Wireless Presenter

Norwii Wireless Presenter

Norwii Wireless Presenter

Norwii Wireless Presenter

3. How can I be sure that customizing the value of the wireless presenter key to the data of the APP path is successful.

In the "Pair" tab, short press the key whose short press function has been customized as "APP Path", and "APP Path + number" and will appear in the white box at the bottom right of the window, which means that the customization of the APP path of the wireless presenter key has been successfully set. According to this method, you can also customize the long press function of the key.

Norwii Wireless Presenter

4. How to get the VID and PID of Norwii Wireless presenter. 

On the [About] tab, find the line that shows "Firmware Information", the right side shows the VID and PID of the wireless presenter, these two values will be used in the USB HID communication. The two values shown on the page are hexadecimal values with 0x omitted, remember to add 0x in front of them when you use them in the program, the VID is hexadecimal value 0x3243 and the PID is hexadecimal value 0x0341 in the following figure, the VID of Norwii wireless presenter is the same, and the PIDs of different product models are different, and the PIDs of the same model are generally the same. The same model and different main control chip will usually have different PID. 

Norwii Wireless Presenter

II. Second, USB HID communication.

1. Referenced files and libraries.

1) #include <windows.h>

2) #include <vector>

3) #include <string>     // Includes the string functions.

4) #include <setupapi.h>   // Includes the SetupAPI.

5) #include "hidapi.h"

6) using namespace std;

7) #pragma comment (lib, "setupapi.lib")

2. Get the path keyword of the HID device interface of the device through VID and PID; such as VID: 0x3243, PID: 0x0341, the path keyword of its HID device interface is "#vid_3243&pid_0341&mi_02&col01# ".

1) string GetNorwiiKeyPath(const int vid, const int pid)

2) {

3)  if (vid == 0x023243 & pid == 0x0352)

4)   return "_dev_vid&023243_pid&0352_rev&0001_";

5)  if (vid == 0x023243 & pid == 0x0361)

6)   return "_dev_vid&023243_pid&0361_rev&0001_";

7)  std::vector<string> vtHidPathKey;

8)  vtHidPathKey.push_back("vid_3243&pid_0111&mi_00&col03");

9)  vtHidPathKey.push_back("vid_3243&pid_0121&mi_01&col02");

10)  vtHidPathKey.push_back("vid_3243&pid_0221&mi_01&col02");

11)  vtHidPathKey.push_back("#vid_3243&pid_0131&mi_00&col03#");

12)  vtHidPathKey.push_back("#vid_3243&pid_1234&mi_00&col03#");

13)  vtHidPathKey.push_back("#vid_3243&pid_0112&mi_00&col03#");

14)  vtHidPathKey.push_back("#vid_3243&pid_0212&mi_00&col03#");

15)  vtHidPathKey.push_back("#vid_3243&pid_0122&mi_01&col03#");

16)  vtHidPathKey.push_back("#vid_3243&pid_0122&mi_02#");

17)  vtHidPathKey.push_back("#vid_3243&pid_0222&mi_01&col03#");

18)  vtHidPathKey.push_back("#vid_3243&pid_0341&mi_02&col01#");

19)  vtHidPathKey.push_back("#vid_3243&pid_0342&mi_02&col01#");

20)  vtHidPathKey.push_back("#vid_3243&pid_0381&mi_02&col01#");

21)  vtHidPathKey.push_back("#vid_3243&pid_0382&mi_02&col01#");

22)

23)  string sKeyPath;

24)  char temp_char[20] = { 0 };

25)  sprintf(temp_char, "&pid_%04x&", pid);

26)  std::vector<string>::iterator iter = vtHidPathKey.begin();

27)  for (; iter != vtHidPathKey.end(); iter++)

28)  {

29)   string sTempKeyPath = *iter;

30)   if (sTempKeyPath.find(temp_char) != string::npos)

31)   {

32)    sKeyPath = sTempKeyPath;

33)    break;

34)   }

35)  }

36)  return sKeyPath;

37) }

3. Traverses the path to the HID device interface for all USB and Bluetooth devices on windows system.

1) string GetDevicePath(HDEVINFO deviceInfoSet, SP_DEVICE_INTERFACE_DATA deviceInterfaceData)

2) {

3)  DWORD bufferSize = 0;

4)  SetupDiGetDeviceInterfaceDetailA(deviceInfoSet, &deviceInterfaceData, NULL, 0, &bufferSize, NULL);

5)

6)  SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;

7)  device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*)malloc(bufferSize);

8)  device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);

9)

10)  string sDevicePath =

11)   SetupDiGetDeviceInterfaceDetailA(deviceInfoSet, &deviceInterfaceData, device_interface_detail_data, bufferSize, &bufferSize, NULL) ?

12)   device_interface_detail_data->DevicePath : "";

13)  free(device_interface_detail_data);

14)  return sDevicePath;

15) }

16)

17) vector<string> EnumeratePath()

18) {

19)  vector<string> devices;

20)  GUID InterfaceClassGuid = { 0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };

21)  //GUID InterfaceClassGuid = { 0xa5dcbf10L, 0x6530, 0x11d2,{0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed} };

22)  HDEVINFO device_info_set = INVALID_HANDLE_VALUE;

23)  //Get information for all the devices belonging to the HID class. 

24)  device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

25)  if (device_info_set != INVALID_HANDLE_VALUE)

26)  {

27)   int device_index = 0;

28)   SP_DEVINFO_DATA devinfo_data;

29)   memset(&devinfo_data, 0x0, sizeof(devinfo_data));

30)   devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);

31)

32)   while (SetupDiEnumDeviceInfo(device_info_set, device_index, &devinfo_data))

33)   {

34)    device_index += 1;

35)

36)    SP_DEVICE_INTERFACE_DATA device_interface_data;

37)    device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

38)    int deviceInterfaceIndex = 0;

39)

40)    while (SetupDiEnumDeviceInterfaces(device_info_set, &devinfo_data, &InterfaceClassGuid, deviceInterfaceIndex, &device_interface_data))

41)    {

42)     deviceInterfaceIndex++;

43)     string devicePath = GetDevicePath(device_info_set, device_interface_data);

44)

45)     devices.push_back(devicePath);

46)    }

47)   }

48)   SetupDiDestroyDeviceInfoList(device_info_set);

49)  }

50)  return devices;

51) }

4. Get the path to the HID device interface where Norwii wireless presenter is communicating with.

Search through the paths of all USB and Bluetooth HID device interfaces on Windows system and check if one of the paths contains the path keyword of the HID device interface introduced earlier.  If there is, the path of the HID device interface is the path of the HID device interface of the VID and PID of the Norwii wireless presenter.

If there is such a path to the HID device interface \\?\hid#vid_3243&pid_0341&mi_02&col01#7&34f72933&0&0000#{4d1e55b2-f16f-11 cf-88cb-001111000030} It contains the path keyword "#vid_3243&pid_0341&mi_02&col01#" of the HID device interface, and the path of this HID device interface is the HID communication path of the VID and PID of the Norwii wireless presenter.

1) string GetNorwiiHidPath(const string &sKeyPath)

2) {

3)  string sCustomizedPath;

4)  vector<string> vtAllPath = EnumeratePath();

5)  for (int k = 0; k < vtAllPath.size(); k++)

6)  {

7)   string rString = vtAllPath[k];

8)   if (rString.find(sKeyPath) != string::npos)

9)   {

10)    if (rString.find("_dev_vid&023243_pid&0352_rev&0001_") != string::npos ||

11)     rString.find("_dev_vid&023243_pid&0361_rev&0001_") != string::npos)

12)    {

13)     if (rString.find("&col03#") == string::npos)

14)      continue;

15)    }

16)    sCustomizedPath = rString;

17)    break;

18)   }

19)  }

20)  return sCustomizedPath;

21) }

5. To open the path of the HID device interface for communication, call the function hid_open_path in the hidapi.h file.

1) string szHidPath = "\\?\hid#vid_3243&pid_0341&mi_02&col01#7&34f72933&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";

2) hid_device *hidHandle = hid_open_path(szHidPath.c_str());

6. To close the path of an opened HID device interface, call thefunction hid_close in the hidapi.h file.

1) if (hidHandle)

2)  {

3)   hid_close(hidHandle);

4)  }

7. Receive HID data, determine the receipt of APP path data, to call the function hid_read_timeout in the hidapi.h file.

1) size_t length = 8;

2)  unsigned char data[8] = { 0 };

3)  int res = hid_read_timeout(hidHandle, data, length, 5);

4)  if (res > 0 && data[0] > 0x00)

5)  {

6)   if (data[0] == 0x03 && data[1] == 0x31 && data[2] == 0x00 && \

7)    data[3] == 0x00 && data[4] == 0x02)

8)   {

9)    int appPath = data[5];//获取到APP通道值

10)    std::cout << "APP Path " << appPath << "\n";

11)   }

12)  }

8. The following code is the whole communication code.

1) struct hid_device_ {

2) HANDLE device_handle;

3) BOOL blocking;

4) USHORT output_report_length;

5) size_t input_report_length;

6) void *last_error_str;

7) DWORD last_error_num;

8) BOOL read_pending;

9) char *read_buf;

10) OVERLAPPED ol;

11) };

12)

13) int main()

14) {

15) string szKeyPath = GetNorwiiKeyPath(0x3243, 0x341);

16) if (!szKeyPath.empty()) 

17) {

18)   string szHidPath = GetNorwiiHidPath(szKeyPath);

19)   if (!szHidPath.empty()) 

20)   {

21)    hid_device *hidHandle = hid_open_path(szHidPath.c_str());

22)    if (hidHandle) 

23)    {

24)     std::cout << "connect success!\n";

25)     int nPendingCount = 0;

26)     size_t length = 8;

27)     unsigned char data[8] = { 0 };

28)     while (true)

29)     {

30)      int res = hid_read_timeout(hidHandle, data, length, 5);

31)      if (res > 0 && data[0] > 0x00)

32)      {

33)       nPendingCount = 0;

34)       if (data[0] == 0x03 && data[1] == 0x31 && data[2] == 0x00 && \

35)        data[3] == 0x00 && data[4] == 0x02)

36)       {

37)        int appPath = data[5];//获取到APP通道值

38)        std::cout << "APP Path " << appPath << "\n";

39)       }

40)       else if (!hidHandle->read_pending)

41)       {

42)        nPendingCount++;

43)        if (nPendingCount > 100)

44)         break;

45)       }

46)      }

47)     }

48)     hid_close(hidHandle);

49)    }

50)   }

51) }

52)  

53)     std::cout << "Hello World!\n"; 

54) system("pause");

55) }

9. Reference code address:

https://www.norwii.com/downloads/presenter/windows/app_path.zip


客服软件