📄 蓝牙虚拟串口与打印机程序.cxx
字号:
if (c >= 'a')
c = c - 'a' + 0xa;
else if (c >= 'A')
c = c - 'A' + 0xa;
else c = c - '0';
if ((c < 0) || (c > 16))
return FALSE;
*pba = *pba * 16 + c;
}
for (i = 0 ; i < 8 ; ++i, ++pp) {
if (! iswxdigit (*pp))
return FALSE;
int c = *pp;
if (c >= 'a')
c = c - 'a' + 0xa;
else if (c >= 'A')
c = c - 'A' + 0xa;
else c = c - '0';
if ((c < 0) || (c > 16))
return FALSE;
*pba = *pba * 16 + c;
}
if ((*pp != ' ') && (*pp != '\0'))
return FALSE;
return TRUE;
}
static void StopDevice (void) {
if (g_pState->hDevice) {
DeregisterDevice (g_pState->hDevice);
g_pState->hDevice = NULL;
}
HKEY hk;
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\printui\\device", 0, KEY_READ, &hk))
return;
WCHAR szName[50];
DWORD dwSize = sizeof(szName);
DWORD dwType;
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"port", NULL, &dwType, (BYTE *)szName, &dwSize)) ||
(dwType != REG_SZ) || (dwSize > sizeof(szName))) {
RegCloseKey (hk);
return;
}
RegCloseKey (hk);
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Printers\\Ports", 0, KEY_ALL_ACCESS, &hk))
return;
WCHAR szPortName[10];
for (int i = 1; i < 10 ; ++i) {
wsprintf (szPortName, L"port%d", i);
WCHAR szString[256];
dwSize = sizeof(szString);
if (ERROR_SUCCESS == RegQueryValueEx (hk, szPortName, NULL, &dwType, (BYTE *)szString, &dwSize)) {
if ((dwType == REG_SZ) && (wcsicmp (szString, szName) == 0)) {
RegDeleteValue (hk, szPortName);
break;
}
}
}
RegCloseKey (hk);
}
static int IsRegistered (void) {
HKEY hk;
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\printui\\device", 0, KEY_ALL_ACCESS, &hk))
return FALSE;
RegCloseKey (hk);
return TRUE;
}
static void Deregister (void) {
StopDevice ();
RegDeleteKey (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\printui\\device");
}
static int GetRegistration (WCHAR *szOut, int cSize) {
if (cSize < 64)
return FALSE;
wcscpy (szOut, L"No bonding");
HKEY hk;
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\printui\\device", 0, KEY_ALL_ACCESS, &hk))
return TRUE;
WCHAR szString[256];
DWORD dwSize = sizeof(szString);
DWORD dwType;
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"port", NULL, &dwType, (BYTE *)szString, &dwSize)) ||
(dwType != REG_SZ) || (dwSize > sizeof(szString))) {
wcscpy (szOut, L"No printer port!");
RegCloseKey (hk);
return TRUE;
}
if ((toupper (szString[0]) != 'C') || (toupper (szString[1]) != 'O') ||
(toupper (szString[2]) != 'M') || (szString[3] < '0') || (szString[3] > '9') ||
(szString[4] != ':') || (szString[5] != '\0')) {
wcscpy (szOut, L"Bad printer port!");
RegCloseKey (hk);
return TRUE;
}
DWORD ndx = szString[3] - '0';
BT_ADDR b;
unsigned char c;
DWORD dwC;
dwSize = sizeof(dwC);
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"channel", NULL, &dwType, (BYTE *)&dwC, &dwSize)) ||
(dwType != REG_DWORD) || (dwSize != sizeof(dwC))) {
RegCloseKey (hk);
return TRUE;
}
c = (unsigned char)dwC;
dwSize = sizeof(szString);
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"device", NULL, &dwType, (BYTE *)szString, &dwSize)) ||
(dwType != REG_SZ) || (dwSize > sizeof(szString))) {
RegCloseKey (hk);
return TRUE;
}
RegCloseKey (hk);
if ((c <= 0) || (c > 31)) {
wcscpy (szOut, L"Bad channel!");
return TRUE;
}
if (! GetBA (szString, &b)) {
wcscpy (szOut, L"Bad address!");
return TRUE;
}
wsprintf (szOut, L"%04x%08x %d %s on COM%d:", GET_NAP(b), GET_SAP(b), c, g_pState->hDevice ? L"Running" : L"Stopped", ndx);
return TRUE;
}
static void CreateDevice (void) {
int imtu = 0;
HKEY hk;
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\printui", 0, KEY_READ, &hk))
return;
DWORD dw;
DWORD dwSize = sizeof(dw);
DWORD dwType;
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"mtu", NULL, &dwType, (BYTE *)&dw, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dw)))
imtu = dw;
RegCloseKey (hk);
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\printui\\device", 0, KEY_READ, &hk))
return;
BT_ADDR b;
unsigned char c;
WCHAR szName[50];
dwSize = sizeof(szName);
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"port", NULL, &dwType, (BYTE *)szName, &dwSize)) ||
(dwType != REG_SZ) || (dwSize > sizeof(szName))) {
MessageBox (NULL, L"Bluetooth printer is not defined (wrong or nonexistent port)!", L"PrintUI Error", MB_OK | MB_TOPMOST);
RegCloseKey (hk);
return;
}
if ((toupper (szName[0]) != 'C') || (toupper (szName[1]) != 'O') ||
(toupper (szName[2]) != 'M') || (szName[3] < '0') || (szName[3] > '9') ||
(szName[4] != ':') || (szName[5] != '\0')) {
MessageBox (NULL, L"Bluetooth printer is not defined (bad port)!", L"PrintUI Error", MB_OK | MB_TOPMOST);
RegCloseKey (hk);
return;
}
DWORD ndx = szName[3] - '0';
DWORD dwC;
dwSize = sizeof(dwC);
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"channel", NULL, &dwType, (BYTE *)&dwC, &dwSize)) ||
(dwType != REG_DWORD) || (dwSize != sizeof(dwC))) {
RegCloseKey (hk);
return;
}
c = (unsigned char)dwC;
WCHAR szString[256];
dwSize = sizeof(szString);
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"device", NULL, &dwType, (BYTE *)szString, &dwSize)) ||
(dwType != REG_SZ) || (dwSize > sizeof(szString))) {
RegCloseKey (hk);
return;
}
RegCloseKey (hk);
if ((c <= 0) || (c > 31)) {
MessageBox (NULL, L"Bad channel in print UI registry!", L"PrintUI Error", MB_OK | MB_TOPMOST);
return;
}
if (! GetBA (szString, &b)) {
MessageBox (NULL, L"Bad address in print UI registry!", L"PrintUI Error", MB_OK | MB_TOPMOST);
return;
}
StopDevice ();
PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.device = b;
pp.channel = c;
pp.uiportflags = 0;
pp.imtu = imtu;
g_pState->hDevice = RegisterDevice (L"COM", ndx, L"btd.dll", (DWORD)&pp);
if (! g_pState->hDevice) {
wsprintf (szString, L"Failed to register COM port, Error = %d", GetLastError ());
MessageBox (NULL, szString, L"PrintUI Error", MB_OK | MB_TOPMOST);
}
if (! g_pState->hDevice)
return;
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Printers\\Ports", 0, KEY_ALL_ACCESS, &hk)) {
MessageBox (NULL, L"Bluetooth printer is not defined (no registry entry)!", L"PrintUI Error", MB_OK | MB_TOPMOST);
return;
}
int iMinPort = 10;
WCHAR szPortName[10];
for (int i = 1; i < 10 ; ++i) {
wsprintf (szPortName, L"port%d", i);
dwSize = sizeof(szString);
if (ERROR_SUCCESS == RegQueryValueEx (hk, szPortName, NULL, &dwType, (BYTE *)szString, &dwSize)) {
if ((dwType == REG_SZ) && (wcsicmp (szString, szName) == 0)) {
RegCloseKey (hk);
return;
}
} else if (iMinPort > i)
iMinPort = i;
}
if (iMinPort > 10) {
RegCloseKey (hk);
MessageBox (NULL, L"Too many printers already defined!", L"PrintUI Error", MB_OK | MB_TOPMOST);
return;
}
wsprintf (szPortName, L"port%d", iMinPort);
RegSetValueEx (hk, szPortName, 0, REG_SZ, (BYTE *)szName, (wcslen (szName) + 1) * sizeof(WCHAR));
RegCloseKey (hk);
}
static void StopSearch (void) {
int fWaitForStop = FALSE;
BthNsLookupServiceEnd ((HANDLE)BTHNS_ABORT_CURRENT_INQUIRY);
g_pState->Lock ();
HWND hWnd = g_pState->hWnd;
if (g_pState->fState != DO_NOTHING) {
g_pState->fState = DO_STOP;
fWaitForStop = TRUE;
}
g_pState->Unlock ();
if (fWaitForStop) {
SetWindowText (hWnd, L"Stopping search...");
for (int i = 0 ; i < 20 ; ++i) {
if (g_pState->fState == DO_NOTHING)
break;
Sleep (1000);
}
SetWindowText (hWnd, L"Print UI");
}
}
static int OK (void) {
g_pState->Lock ();
HWND hWnd = g_pState->hWnd;
HINSTANCE hInst = g_pState->hInst;
g_pState->Unlock ();
StopSearch ();
HWND hWndDevList = GetDlgItem (hWnd, IDC_DEVICELIST);
int iNdx = SendMessage (hWndDevList, LB_GETCURSEL, 0, 0);
if (iNdx < 0) {
MessageBox (hWnd, L"Nothing selected", L"Error", MB_OK | MB_TOPMOST);
return FALSE;
}
int iItemData = SendMessage (hWndDevList, LB_GETITEMDATA, (WPARAM)iNdx, (LPARAM)0);
g_pState->Lock ();
InquiryResult *pRes = g_pState->pDev;
while (pRes && (pRes != (InquiryResult *)iItemData))
pRes = pRes->pNext;
if (! pRes) {
g_pState->Unlock ();
MessageBox (hWnd, L"Please requery. This record is obsolete.", L"Error", MB_OK | MB_TOPMOST);
return FALSE;
}
BT_ADDR b = pRes->b;
unsigned char c = pRes->channel;
int fHaveSDP = pRes->fHaveSDP;
g_pState->Unlock ();
if (! fHaveSDP) {
SVSUTIL_ASSERT (! c);
c = DoSDP (&b);
}
if (! c)
c = DialogBox (hInst, MAKEINTRESOURCE (IDD_ENTERCHANNEL), NULL, DlgProc2);
if ((c <= 0) || (c >= 32))
return FALSE;
HKEY hk;
DWORD dwDisp;
if (ERROR_SUCCESS == RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"software\\microsoft\\bluetooth\\printui\\device", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, &dwDisp)) {
WCHAR szAddress[13];
DWORD dw = c;
wsprintf (szAddress, L"%04x%08x", GET_NAP(b), GET_SAP(b));
RegSetValueEx (hk, L"device", 0, REG_SZ, (BYTE *)szAddress, sizeof(szAddress));
RegSetValueEx (hk, L"channel", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw));
DWORD dwType = 0;
WCHAR szPortName[50];
DWORD cPortName = sizeof(szPortName);
if ((ERROR_SUCCESS != RegQueryValueEx (hk, L"port", NULL, &dwType, (BYTE *)szPortName, &cPortName)) ||
(dwType != REG_SZ) || (cPortName > sizeof(szPortName)) || (wcsnicmp (szPortName, L"COM", 3) != 0) ||
(szPortName[3] <'0') || (szPortName[3] > '9') || (szPortName[4] != '\0'))
RegSetValueEx (hk, L"port", 0, REG_SZ, (BYTE *)DEFAULT_PRINTER_PORT, sizeof(DEFAULT_PRINTER_PORT));
RegCloseKey (hk);
}
CreateDevice ();
return TRUE;
}
static void SetButtonStates (HWND hWnd) {
EnableWindow (GetDlgItem (hWnd, IDC_DEREGISTER), IsRegistered ());
SetWindowText (GetDlgItem (hWnd, IDC_STARTSTOP), g_pState->hDevice ? L"STOP" : L"START");
WCHAR szText[128];
SetWindowText (GetDlgItem (hWnd, IDC_CURRENT), GetRegistration (szText, 128) ? szText : L"ERROR");
}
static BOOL CALLBACK DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_INITDIALOG:
g_pState->hWnd = hWnd;
SetButtonStates (hWnd);
SetForegroundWindow (hWnd);
SetFocus (GetDlgItem (hWnd, IDCANCEL));
SendMessage(GetDlgItem(hWnd, IDC_DEVICELIST), LB_SETHORIZONTALEXTENT, 250, 0);
return 0;
case WM_COMMAND:
{
int wID = LOWORD(wParam);
switch (wID)
{
case IDOK:
if (OK ())
EndDialog (hWnd, TRUE);
return 0;
case IDCANCEL:
StopSearch ();
EndDialog (hWnd, TRUE);
return 0;
case IDC_EXIT:
StopSearch ();
EndDialog (hWnd, FALSE);
return 0;
case IDC_STARTSTOP:
if (g_pState->hDevice)
StopDevice ();
else
CreateDevice ();
SetButtonStates (hWnd);
break;
case IDC_DEREGISTER:
Deregister ();
SetButtonStates (hWnd);
break;
case IDC_INQUIRY: // Inquiry
CreateThread (NULL, 0, DoInquiry, NULL, 0, NULL);
break;
}
}
break;
}
return 0;
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_CREATE:
return 0;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_USER + 1:
if (lParam == WM_LBUTTONDOWN) {
if (g_pState->hWnd) {
SetForegroundWindow (g_pState->hWnd);
break;
}
if (! DialogBox (g_pState->hInst, MAKEINTRESOURCE (IDD_MAINBOX), NULL, DlgProc)) {
NOTIFYICONDATA nid;
memset (&nid, 0, sizeof(nid));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = 1;
Shell_NotifyIcon (NIM_DELETE, &nid);
DestroyWindow (hWnd);
}
g_pState->Lock ();
g_pState->hWnd = NULL;
g_pState->fState = DO_NOTHING;
CleanInquiryData ();
g_pState->Unlock ();
}
break;
case WM_USER + 5:
{
if (g_pState->hWnd) {
SetForegroundWindow (g_pState->hWnd);
break;
}
NOTIFYICONDATA nid;
memset (&nid, 0, sizeof(nid));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = 1;
Shell_NotifyIcon (NIM_DELETE, &nid);
DestroyWindow (hWnd);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return FALSE;
}
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPWSTR lpszCmdLine, int nCmdShow) {
for (int i = 0 ; (i < 10) && (! IsAPIReady(SH_WMGR)); ++i) //Wait for shell
Sleep(1000);
g_pState = new Global;
if (! g_pState)
return 0;
g_pState->hInst = hInst;
WNDCLASS wc;
memset (&wc, 0, sizeof(wc));
wc.lpfnWndProc = WndProc;
wc.hInstance = hInst;
wc.lpszClassName = APPNAME;
if (! RegisterClass (&wc))
return 0;
g_pState->hWndHidden = CreateWindow (APPNAME, APPNAME, WS_DISABLED,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
NOTIFYICONDATA nid;
memset (&nid, 0, sizeof(nid));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = g_pState->hWndHidden;
nid.uID = 1;
nid.uFlags = NIF_ICON | NIF_MESSAGE;
nid.uCallbackMessage = WM_USER + 1;
nid.hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_BTHICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
if (wcsstr (lpszCmdLine, L"/noicon") == 0)
Shell_NotifyIcon (NIM_ADD, &nid);
CreateDevice ();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage (&msg) ;
DispatchMessage(&msg);
}
StopDevice ();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -