ActiveX C++控制 WriteFile 在 4 次尝试后失败
我有一个用 C++ 编写的 ActiveX HTML 对象。该代码用于打印到蓝牙打印机。我能够成功调用代码 4 次(如下所示),然后“WriteFile”函数开始返回“0”。当我关闭浏览器并再次打开它时,它可以再尝试 4 次...所以这肯定看起来像内存泄漏或其他什么,但不幸的是我对 C++ 不太擅长...所以我在这里一些帮助:)
BOOL RegGetValue(HKEY hRootKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbDataLen)
{
LRESULT lResult = -1;
HKEY hKey = NULL;
lResult =RegOpenKeyEx(hRootKey, lpSubKey, 0, 0, &hKey);
int e = GetLastError();
if (lResult == ERROR_SUCCESS)
{
lResult = RegQueryValueEx(hKey, lpValueName, NULL, lpType, lpData, lpcbDataLen);
e = GetLastError();
RegCloseKey(hKey);
}
return (lResult == ERROR_SUCCESS);
}
#define MSS_PORTS_BASE _T("Software\\Microsoft\\Bluetooth\\Serial\\Ports")
bool FindBluetoothPort(TCHAR name[16])
{
HKEY hKey, hRoot;
TCHAR szPort[20] = _T(""), szPortString[20];
DWORD len, dwIndex=0;
bool bFound=false;
INT i = 0, rc;
DWORD dwNSize;
DWORD dwCSize;
TCHAR szClass[256];
TCHAR szName[MAX_PATH];
FILETIME ft;
hRoot = HKEY_LOCAL_MACHINE;
if (RegOpenKeyEx (hRoot, MSS_PORTS_BASE, 0, 0, &hKey) != ERROR_SUCCESS)
{ rc = GetLastError();
return 0;
}
dwNSize = dim(szName);
dwCSize = dim(szClass);
rc = RegEnumKeyEx (hKey, i, szName, &dwNSize, NULL, szClass, &dwCSize, &ft);
while (rc == ERROR_SUCCESS)
{
// how many children
TCHAR szCurrentKey[MAX_PATH];
wcscpy(szCurrentKey, MSS_PORTS_BASE);
wcscat(szCurrentKey, TEXT("\\"));
wcscat(szCurrentKey, szName);
wcscat(szCurrentKey, TEXT("\\"));
len = sizeof(szPort);
if(RegGetValue(hRoot, szCurrentKey, _T("Port"), NULL, (LPBYTE)szPort, &len))
{
wsprintf(szPortString, _T("%s:"), szPort);
bFound = true;
break;
}
dwNSize = dim(szName);
rc = RegEnumKeyEx(hKey, ++i, szName, &dwNSize, NULL, NULL, 0, &ft);
}
if(bFound)
_tcscpy(name, szPortString);
return bFound;
}
WriteFile(
HANDLE hFile,
__in_bcount(nNumberOfBytesToWrite) LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
void CHSMBTPrintXCtrl::PrintLabel(void)
{
//MessageBox(TEXT("Started"), TEXT("HSMBTPrintX"), MB_OK);
TCHAR g_szComPort[16];
char szout[900];
TCHAR comPort[16];
HANDLE hCom;
unsigned long bytesWritten;
int counter;
for (counter = 0; counter < 900; counter++)
szout[counter] = NULL;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!FindBluetoothPort(g_szComPort))
{
MessageBox(TEXT("No Port Found"), TEXT("HSMBTPrintX"), MB_OK);
return;
}
//Try at least 3 times to get a valid handle
for(counter = 0; counter < 2; ++counter)
{
hCom = CreateFile(g_szComPort,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (hCom)
break;
}
if (hCom == NULL)
{
MessageBox(TEXT("Could not open file to print"), TEXT("HSMBTPrintX"), MB_OK);
return;
}
CT2CA date(COleDateTime::GetCurrentTime().Format(L"%m/%d/%y"));
CT2CA time(COleDateTime::GetCurrentTime().Format(L"%H:%M"));
if (m_actionParameter == "SKUTagPrint") {
CT2CA department (m_departmentParameter);
CT2CA sku (m_skuParameter);
for (counter = 0; counter < 900; counter++)
szout[counter] = NULL;
strcpy(szout, "^XA\n");
strcat(szout, "SomeTextHere");
//more strcat lines here
if(WriteFile(hCom,szout,900,&bytesWritten,NULL)==0) {
MessageBox(TEXT("Unable to write file"), TEXT("HSMBTPrintX"), MB_OK);
return;
}
}
// MessageBox(m_barcodeParameter, TEXT("HSMBTPrintX"), MB_OK);
// Create text to send to printer
FireLabelPrinted();
return;
}
// HTML
<object id="HSMBTPrintX1" width="350" height="350"
classid="CLSID:68D05400-18A6-4B39-B3FF-A17D77C1EDDF"
codebase=".\..\HSMBTPrintX.ocx#1,0,0,1" style="display:none;">
</object>
<script type="text/javascript" for="HSMBTPrintX1" event="LabelPrinted()">
alert('Label(s) successfully printed.');
</script>
// Javascript
HSMBTPrintX1.sizeParameter = document.getElementById("tdSize").innerText;
HSMBTPrintX1.actionParameter = "SKUTagPrint";
HSMBTPrintX1.PrintLabel();
I have an ActiveX HTML object written in C++. The code is used to print to a bluetooth printer. I am able to make 4 successful calls to the code (shown below) and then the "WriteFile" function starts returning "0". When I shut down the browser and open it up again, it works for another 4 trys... so this sure seems like a memory leak or something, but i'm not very good with C++ unfortunately... so here i am for some help :)
BOOL RegGetValue(HKEY hRootKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbDataLen)
{
LRESULT lResult = -1;
HKEY hKey = NULL;
lResult =RegOpenKeyEx(hRootKey, lpSubKey, 0, 0, &hKey);
int e = GetLastError();
if (lResult == ERROR_SUCCESS)
{
lResult = RegQueryValueEx(hKey, lpValueName, NULL, lpType, lpData, lpcbDataLen);
e = GetLastError();
RegCloseKey(hKey);
}
return (lResult == ERROR_SUCCESS);
}
#define MSS_PORTS_BASE _T("Software\\Microsoft\\Bluetooth\\Serial\\Ports")
bool FindBluetoothPort(TCHAR name[16])
{
HKEY hKey, hRoot;
TCHAR szPort[20] = _T(""), szPortString[20];
DWORD len, dwIndex=0;
bool bFound=false;
INT i = 0, rc;
DWORD dwNSize;
DWORD dwCSize;
TCHAR szClass[256];
TCHAR szName[MAX_PATH];
FILETIME ft;
hRoot = HKEY_LOCAL_MACHINE;
if (RegOpenKeyEx (hRoot, MSS_PORTS_BASE, 0, 0, &hKey) != ERROR_SUCCESS)
{ rc = GetLastError();
return 0;
}
dwNSize = dim(szName);
dwCSize = dim(szClass);
rc = RegEnumKeyEx (hKey, i, szName, &dwNSize, NULL, szClass, &dwCSize, &ft);
while (rc == ERROR_SUCCESS)
{
// how many children
TCHAR szCurrentKey[MAX_PATH];
wcscpy(szCurrentKey, MSS_PORTS_BASE);
wcscat(szCurrentKey, TEXT("\\"));
wcscat(szCurrentKey, szName);
wcscat(szCurrentKey, TEXT("\\"));
len = sizeof(szPort);
if(RegGetValue(hRoot, szCurrentKey, _T("Port"), NULL, (LPBYTE)szPort, &len))
{
wsprintf(szPortString, _T("%s:"), szPort);
bFound = true;
break;
}
dwNSize = dim(szName);
rc = RegEnumKeyEx(hKey, ++i, szName, &dwNSize, NULL, NULL, 0, &ft);
}
if(bFound)
_tcscpy(name, szPortString);
return bFound;
}
WriteFile(
HANDLE hFile,
__in_bcount(nNumberOfBytesToWrite) LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
void CHSMBTPrintXCtrl::PrintLabel(void)
{
//MessageBox(TEXT("Started"), TEXT("HSMBTPrintX"), MB_OK);
TCHAR g_szComPort[16];
char szout[900];
TCHAR comPort[16];
HANDLE hCom;
unsigned long bytesWritten;
int counter;
for (counter = 0; counter < 900; counter++)
szout[counter] = NULL;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!FindBluetoothPort(g_szComPort))
{
MessageBox(TEXT("No Port Found"), TEXT("HSMBTPrintX"), MB_OK);
return;
}
//Try at least 3 times to get a valid handle
for(counter = 0; counter < 2; ++counter)
{
hCom = CreateFile(g_szComPort,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (hCom)
break;
}
if (hCom == NULL)
{
MessageBox(TEXT("Could not open file to print"), TEXT("HSMBTPrintX"), MB_OK);
return;
}
CT2CA date(COleDateTime::GetCurrentTime().Format(L"%m/%d/%y"));
CT2CA time(COleDateTime::GetCurrentTime().Format(L"%H:%M"));
if (m_actionParameter == "SKUTagPrint") {
CT2CA department (m_departmentParameter);
CT2CA sku (m_skuParameter);
for (counter = 0; counter < 900; counter++)
szout[counter] = NULL;
strcpy(szout, "^XA\n");
strcat(szout, "SomeTextHere");
//more strcat lines here
if(WriteFile(hCom,szout,900,&bytesWritten,NULL)==0) {
MessageBox(TEXT("Unable to write file"), TEXT("HSMBTPrintX"), MB_OK);
return;
}
}
// MessageBox(m_barcodeParameter, TEXT("HSMBTPrintX"), MB_OK);
// Create text to send to printer
FireLabelPrinted();
return;
}
// HTML
<object id="HSMBTPrintX1" width="350" height="350"
classid="CLSID:68D05400-18A6-4B39-B3FF-A17D77C1EDDF"
codebase=".\..\HSMBTPrintX.ocx#1,0,0,1" style="display:none;">
</object>
<script type="text/javascript" for="HSMBTPrintX1" event="LabelPrinted()">
alert('Label(s) successfully printed.');
</script>
// Javascript
HSMBTPrintX1.sizeParameter = document.getElementById("tdSize").innerText;
HSMBTPrintX1.actionParameter = "SKUTagPrint";
HSMBTPrintX1.PrintLabel();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要将
CreateFile()
与CloseHandle()
相匹配,否则可能会发生奇怪的事情,请参阅:http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspxYou need to match a
CreateFile()
with aCloseHandle()
or odd things can happen, see: http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx