CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

线程里调用函数会失败,但是若不在线程内调用却正常,请问为什么呢?

楼主xhwu3721(阿华)2006-06-01 15:36:24 在 VC/MFC / 基础类 提问

问题:如果我在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

相关问题

关键词

得分解答快速导航

  • 帖主:xhwu3721
  • jacklzw88
  • Qiushen
  • wangk
  • abuseyoudna1981
  • jacklzw88
  • jacklzw88
  • zxyjyzxyjy
  • abuseyoudna1981

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo