线程里调用函数会失败,但是若不在线程内调用却正常,请问为什么呢?
问题:如果我在OnBnClickedStarttransfer()函数中直接调用FindMTPDevice()函数,一切正常,能找到设备,返回TRUE,但如果在线程中调用,却总是返回FALSE,结果正好相反,真搞不懂.
过程如下:
在对话框程序创建一个线程.
在CTransferMusicDlg.cpp中定义.
extern BOOL FindMTPDevice();
DWORD WINAPI StartMTPThread(LPVOID lp);
DWORD WINAPI StartMTPThread(LPVOID lp)
{
CTransferMusicDlg *pDlg = (CTransferMusicDlg*)lp;
while(1)
{
if(pDlg->bMTPTimerStart)
break;
Sleep(100);
}
if(FindMTPDevice())
AfxMessageBox("find OK");
else
AfxMessageBox("No find");
return 0L;
}
void CTransferMusicDlg::OnBnClickedStarttransfer()
{
DWORD dwStartMTPThrdId;
HANDLE hStartMTPThrd;
hStartMTPThrd=CreateThread(NULL,0,StartMTPThread,this,0,&dwStartMTPThrdId);
if(hStartMTPThrd==NULL)
{
KillTimer(2);
AfxMessageBox("can't create the start thrd!");
return;
}
CloseHandle(hStartMTPThrd);
}
找设备的函数是定义在mtp.cpp中:
BOOL FindMTPDevice(void)
{
DeviceInit();
WCHAR FAR wDeviceName[256];
UINT uMaxSize = 50;
for(UINT i =0;i<ulFetched;i++)
{
pAllWmdmDevices[i]->GetName(wDeviceName,uMaxSize);
strDeviceName = wDeviceName;
strDeviceName.TrimRight();
if (strcmp(strDeviceName,"Dell DJ Ditty")==0)
{
pIDevice = pAllWmdmDevices[i];
break;
}
}
if(pIDevice==0||ulFetched==0)
{
//AfxMessageBox("can't connect to the device");
return FALSE;
}
return TRUE;
}
问题点数:100、回复次数:14Top
1 楼jacklzw88(不可爱咯)回复于 2006-06-01 15:39:17 得分 10
bMTPTimerStart是不是控件?
线程里是不能使用主窗口的控件的。只能发消息Top
2 楼Qiushen(忘魂)回复于 2006-06-01 15:39:23 得分 10
看一下错误码是什么,查看看
GetLastError()
还有,有没有可能栈空间不够的问题
Top
3 楼wangk(倒之)回复于 2006-06-01 15:40:30 得分 10
试试在线程里建立消息循环。Top
4 楼abuseyoudna1981()回复于 2006-06-01 15:41:33 得分 10
你用的是MFC吧?为什么还用CreateThread?在MFC中用这个?
MFC就改用AfxBeginThread吧.Top
5 楼jacklzw88(不可爱咯)回复于 2006-06-01 15:41:34 得分 10
看错了。不过,一般你这样的问题都是这个问题:)Top
6 楼xhwu3721(阿华)回复于 2006-06-01 15:46:21 得分 0
我使用过消息,也使用过AfxBeginThread(),结果都一样.
DWORD WINAPI StartMTPThread(LPVOID lp)
{
CTransferMusicDlg *pDlg = (CTransferMusicDlg*)lp;
while(1)
{
if(pDlg->bMTPTimerStart) //这只是一个变量,没事的
break;
Sleep(100);
}
pDlg->SendMessage(WM_MESSAGE_MTPTR);
return 0L;
}
LRESULT CTransferMusicDlg::OnMessageMTPTr(WPARAM wParam,LPARAM lParam)
{
WCHAR wDir[]=L"test";
CString strSourceDirList[10] ;
strSourceDirList[0]="d:\\song\\tt.mp3";
if(FindMTPDevice())
{
if(TransferFile(strSourceDirList,wDir))
AfxMessageBox("Transfer file ok");
else
AfxMessageBox("Transfer file fail");
}
startTransfileFlag=FALSE;
return 0L;
}Top
7 楼jacklzw88(不可爱咯)回复于 2006-06-01 15:52:38 得分 10
调试过在哪返回的false吗?Top
8 楼zxyjyzxyjy(猜)回复于 2006-06-01 15:55:47 得分 30
在你的这个函数中FindMTPDevice是否用到了COM对象之类的东西?
用导向生成的对话框应用程序的主线程是自动进行了COM的初始化工作的。Top
9 楼gao_ming77(小明)回复于 2006-06-01 15:56:09 得分 0
ulFetched在哪儿定义的?Top
10 楼abuseyoudna1981()回复于 2006-06-01 16:02:18 得分 10
在对话框类里面声明线程函数吧.
CXXXDLG.h
Class CXXXDLG:public CDialog
.....
protected:
static UINT ThreadProc(LPVOID lParam);
.......
AfxBeginThread(ThreadProc,this);
UINT CXXXDLG::ThreadProc(LPVOID lParam){
CXXXDLG* dd=(CXXXDLG*)lParam;
dd->FindMTPDevice();
.........
return 0;
}
Top
11 楼xhwu3721(阿华)回复于 2006-06-01 16:26:02 得分 0
TO:abuseyoudna1981() 谢谢!在对话框类里面声明线程函数刚刚试了一下也不行.真是怪了.
TO:zxyjyzxyjy(星星) 谢谢!
我用到了media player 10 series SDK,代码如下,不知道它是不是com,该如何解决呢?
void DeviceInit()
{
HRESULT hr;
IComponentAuthenticate* pICompAuth;
CSecureChannelClient SAC;
IWMDMEnumDevice* pIEnumDev;
IWMDeviceManager* pIdvMgr;
ULONG ulNum = 1;
DWORD dwNumProtCount;
DWORD* pdwProt; // This will always be SAC_PROTOCOL_V1.
UINT iStrLength;
CString string;
CString temp ;
DWORD dwCount;
WCHAR lwManufacturer[256];
WMDMID SerialNumberStruct;
PWMDMID pSerialNumberStruct;
UINT deviceNameLength;
pSerialNumberStruct =&SerialNumberStruct;
CoInitialize(NULL);
hr = ::CoCreateInstance(CLSID_MediaDevMgr,
NULL,
CLSCTX_ALL,
IID_IComponentAuthenticate,(void **)&pICompAuth);
// After getting IComponentAuthenticate, the authentication progression follows.
if SUCCEEDED(hr)
{
hr = SAC.SetCertificate(SAC_CERT_V1, (BYTE*) abCert, sizeof(abCert), (BYTE*) abPVK, sizeof(abPVK));
if SUCCEEDED(hr)
{
// Set interface for Secure Authenticated Channel
// operations. The return value of this function is void.
SAC.SetInterface(pICompAuth);
hr = pICompAuth->SACGetProtocols(&pdwProt, &dwNumProtCount);
if SUCCEEDED(hr)
hr = SAC.Authenticate(*pdwProt); //SAC_PROTOCOL_V1
//if SUCCEEDED(hr)
// ;
}
if(pdwProt)
CoTaskMemFree(pdwProt);
// After authentication has succeeded, call QueryInterface to
// get IID_IWMDeviceManager.
hr = pICompAuth->QueryInterface(IID_IWMDeviceManager, (void**)&pIdvMgr);
if SUCCEEDED(hr)
{
hr = pIdvMgr->GetDeviceCount(&dwCount);
if SUCCEEDED(hr)
{
}
}
hr = pIdvMgr->EnumDevices(&pIEnumDev); // Query for device enumerator.
if SUCCEEDED(hr)//sart pIEnumDev
{
// Get device.
nDeviceCount = 0;
ULONG k;
while(TRUE)
{
hr = pIEnumDev->Next(ulDevicesCount, pAllWmdmDevices, &ulFetched);
if(FAILED(hr))
{
//AfxMessageBox("EnumDevice Failed");
return;
}
for(k = 0; k < ulFetched; k++)
{
if(pAllWmdmDevices[k] == NULL)
continue;
IWMDMDevice2* pWmdmDevice2;
if(pAllWmdmDevices[k]==0)
{
// AfxMessageBox("Can't connect to the device");
return;
}
hr = pAllWmdmDevices[k]->QueryInterface(IID_IWMDMDevice2, (void **)&pWmdmDevice2);
if(FAILED(hr))
{
//AfxMessageBox("No players could be find");
return;
}
deviceNameLength = 50;
iStrLength = 256;
pAllWmdmDevices[k]->GetManufacturer(lwManufacturer, iStrLength);
CString strTemp;
strTemp = lwManufacturer;
strTemp.TrimRight();
if (strcmp(strTemp, "Dell Inc") == 0)
{
nDeviceCount++;
pAllWmdmDevices[k]->GetName(m_pwsString,deviceNameLength);
m_strDeviceName.Add( LPCTSTR(m_pwsString));
m_strDevManufacture.Add(LPCTSTR(lwManufacturer));
}
if(nDeviceCount==0)
{
//AfxMessageBox("Can't connect to the device");
return;
}
}//end for
if(ulFetched < ulDevicesCount)
break;
}//end while
}//end pIEnumDev if
else
{
//AfxMessageBox("No players could be find");
return;
}
}
startInsertListFlag = TRUE;
}
BOOL FindMTPDevice(void)
{
DeviceInit();
WCHAR FAR wDeviceName[256];
UINT uMaxSize = 50;
for(UINT i =0;i<ulFetched;i++)
{
pAllWmdmDevices[i]->GetName(wDeviceName,uMaxSize);
strDeviceName = wDeviceName;
strDeviceName.TrimRight();
if (strcmp(strDeviceName,"Dell DJ Ditty")==0)
{
pIDevice = pAllWmdmDevices[i];
break;
}
}
if(pIDevice==0||ulFetched==0)
{
//AfxMessageBox("can't connect to the device");
return FALSE;
}
return TRUE;
}
Top
12 楼wangk(倒之)回复于 2006-06-01 16:42:29 得分 0
确实用到COM了。
方法一:按zxyjyzxyjy所说用CoInitializeEx来初始化COM
方法二:给对话框发送消息,然后在消息处理函数中FindMTPDevice。Top
13 楼xhwu3721(阿华)回复于 2006-06-01 16:52:36 得分 0
to:wangk(倒之)
方法一:我己经在FindMTPDevice()函数中用了CoInitialize()来进行初始化啊,上面代码中有.
方法二:我有做过在线程中发消息,在消息处理函数中调用FindMTPDevice(),但还是一样啊.Top
14 楼gao_ming77(小明)回复于 2006-06-01 16:58:24 得分 0
你调试一下看看哪儿返回false?Top




