获取线程函数的句柄

时间:2011-06-30 08:34:18

标签: c windows winapi

整码下载:http://tunps.com/tmp/UsbAutoCopy.zip program screen shot

这是WinMain:

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPSTR lpCmdLine, int nCmdShow )
{
        DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN),
                  hWnd, DlgProc);

  return 0;
}

在全球范围内:

typedef struct ArgsTag {
    CHAR vol;
    HWND hWndDlg;
} Args, *pArgs;
消息循环中的

pArgs arg;
arg = malloc(sizeof(struct ArgsTag));
arg->vol= FirstDriveFromMask(lpdbv->dbcv_unitmask);
arg->hWndDlg = hWndDlg;
_beginthread ((LPVOID)CopyThread, 0, (LPVOID)arg) ;

这是Dialog过程函数原型:

LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam);

得到正确的arg->vol,但arg->hWndDlg返回错误的地址。

在CopyThread线程中

,我想获得主窗口句柄(hWndDlg)。

hLog = GetDlgItem(arg->hWndDlg,IDC_LOG);
在谷歌很多之后,我仍然一无所获,所以我如何获得正确的hWndDlg孩子HWND?

顺便说一句,大小信息

sizeof(args) = 4

sizeof(ArgsTag) = 8

sizeof(args->vol) = 1

sizeof(args->hWndDlg) = 4

更新:2011.07.01

好吧,我现在对这个问题非常生气。

我想发布整个代码,编译 visual c ++ 6.0 / win32应用程序

这是一个usb自动复制程序,它可以检测插入的USB存储设备,并将USB存储设备上的指定文件路径复制到硬盘上的指定目录,同时显示程序右侧编辑框中的日志。 / p>

uac.c

#include <windows.h>
#include <iostream.h>
#include <process.h>
#include <stdio.h>
#include <dbt.h>
#include <Shlobj.h>
#include "resource.h"
#include "Shlwapi.h"

//---------------------------------------------------------------------------
#define _TRACE true;
DEV_BROADCAST_HDR* dhr;
PDEV_BROADCAST_VOLUME lpdbv;
//OPENFILENAME ofn;
BROWSEINFO bi;
LPITEMIDLIST lpItemIdList;
HWND hWnd;
static HICON hIcon,hIconSm;
HANDLE hFile,hFileList,hDstDir,hLog,hBtnSave,hBtnBrowse;
DWORD err,dwWritenSize = 0;
CHAR vol,bufFileList[1024],bufDstDir[MAX_PATH],subStr[1024],buf[1024],buf2[1024],deviceID[1024];
TCHAR szPath[_MAX_PATH];
PCHAR pvol;
LPCTSTR configFileName = "D:\\win32dev\\sdk\\UsbAutoCopy\\Debug\\config.ini";
//LPSTR szPath;
UINT i,len,j=0;k=0;
FILE *stream;
char buflist[1000][1024]={0};
typedef struct ArgsTag {
    HWND hWndDlg;
    CHAR vol;    
} Args, *pArgs;
LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
LPTSTR ReadConfigFile(LPTSTR key);
BOOL WriteConfigFile(TCHAR *bufFileList,TCHAR *bufDstDir);
int ReplaceStr(char *sSrc, char *sMatchStr, char *sReplaceStr);
char FirstDriveFromMask (ULONG unitmask); //prototype
void CopyThread(CHAR vol);
char* getFileName(char* dirName);
/************************************************************************/
/* e.g: \1.txt->\1.txt      \dir1\dir2\test.exe->\test.exe              */
/************************************************************************/
char* getFileName(char* dirName)
{

    unsigned int i,j=0;
    //buf={0};
    for(i=strlen(dirName);i>=0;i--)
    {
        //fileName[j++] = dirName[i];
        if(dirName[i] == '\\')
        {
            for(j=0;j<strlen(dirName);)
                buf[j++] = dirName[i++];
            break;
        }
    }
    return buf;
}
void CopyThread(pArgs arg)
{
    char temp[1024];
    pvol = &(arg->vol);
    pvol[1] = 0;
    //GetPrivateProfileString("config","DeviceID","",buf,sizeof(buf),strcat(pvol,":\\dp\\device.ini")); 没有section无法读取DeviceID
    strcat(pvol,":\\dp\\device.ini");
    //hFile = CreateFile(pvol,GENERIC_READ,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    //ReadFile((HANDLE)hFile,buf,sizeof(buf)/2,&dwWritenSize,NULL);

    // get the Device ID
   if( (stream = fopen( pvol, "r" )) != NULL )
   {
       while(fgets( buf, sizeof(buf), stream ))
       {
           if(i=strstr(buf,"DeviceID=") != NULL)
           {
               sscanf( buf, "DeviceID=%s",deviceID);
               break;
           }
       }
       fclose( stream );
       //make dir named with DeivceID
       GetWindowText(hFileList,bufFileList,sizeof(bufFileList)/sizeof(TCHAR));
       GetWindowText(hDstDir,bufDstDir,sizeof(bufDstDir)/sizeof(TCHAR));
       strcpy(temp,bufDstDir);
       strcat(temp,"\\");
       CreateDirectory(strcat(temp,deviceID),NULL);
       //started to copy and show log
        len = strlen(bufFileList);
        for(i=0;i<len;i++)
        {
            buflist[j][k++] =  bufFileList[i];
            if(bufFileList[i] == '\n')
            {   
                k--;
                buflist[j][k] =0;
                buflist[j][--k] =0;
                j++;
                k=0;
            }
        }
       for(j=0;buflist[j][0] != 0;j++)
       {
            pvol = &(arg->vol);
            pvol[1] = 0;
            strcat(pvol,":");
            strcat(pvol,buflist[j]);
            strcpy(temp,bufDstDir);
            strcat(temp,"\\");
            strcat(temp,deviceID);
            CopyFile(pvol,strcat(temp,getFileName(buflist[j])),FALSE);
            //set log
            hLog = GetDlgItem(arg->hWndDlg,IDC_LOG);
            GetWindowText(hLog,buf2,sizeof(buf2));
            wsprintf(subStr,"#复制文件【】到【】...\r\n");
            strcat(buf2,subStr);
            SetWindowText(hLog,buf2);
       }

    }
    else
    {
        MessageBox(NULL,NULL,"无法打开Device.ini文件",MB_ICONINFORMATION);
    }
}
// 替换字符串中特征字符串为指定字符串
int ReplaceStr(char *sSrc, char *sMatchStr, char *sReplaceStr)
{
    int  StringLen;
    char caNewString[1024];

    char *FindPos = strstr(sSrc, sMatchStr);
    if( (!FindPos) || (!sMatchStr) )
        return -1;

    while( FindPos )
    {
        memset(caNewString, 0, sizeof(caNewString));
        StringLen = FindPos - sSrc;
        strncpy(caNewString, sSrc, StringLen);
        strcat(caNewString, sReplaceStr);
        strcat(caNewString, FindPos + strlen(sMatchStr));
        strcpy(sSrc, caNewString);

        FindPos = strstr(sSrc, sMatchStr);
    }

    return 0;
}
LPTSTR ReadConfigFile(LPTSTR key)
{
    HANDLE hFile = CreateFile(configFileName,GENERIC_READ,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    err=GetLastError();
    CloseHandle(hFile);
    if(err == 2) // file not exists
    {
        HANDLE hFile = CreateFile(configFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
        CloseHandle(hFile);
//      err=GetLastError();
//      sprintf(buf,"%d",err);
//      MessageBox(NULL,buf,NULL,0);
    }
    else
    {
        //load config to app
        GetPrivateProfileString("config","filelist","",bufFileList,sizeof(bufFileList),configFileName);
        GetPrivateProfileString("config","dstdir","",bufDstDir,sizeof(bufDstDir),configFileName);
        ReplaceStr(bufFileList,";","\r\n");
        if(strcmp(key,"filelist") == 0)
            return bufFileList;
        if(strcmp(key,"dstdir") == 0)
            return bufDstDir;
    }
    return NULL;
}
BOOL WriteConfigFile(TCHAR *bufFileList,TCHAR *bufDstDir)
{
    ReplaceStr(bufFileList,"\r\n",";");
    i=WritePrivateProfileString("config","filelist",bufFileList,configFileName);
    WritePrivateProfileString("config","dstdir",bufDstDir,configFileName);
    return TRUE;
}
/*------------------------------------------------------------------
 FirstDriveFromMask (unitmask)

 Description
  Finds the first valid drive letter from a mask of drive letters.
  The mask must be in the format bit 0 = A, bit 1 = B, bit 2 = C, 
  and so on. A valid drive letter is defined when the 
  corresponding bit is set to 1.

 Returns the first drive letter that was found.
--------------------------------------------------------------------*/

char FirstDriveFromMask (ULONG unitmask)
{
 char i;

 for (i = 0; i < 26; ++i)
 {
  if (unitmask & 0x1)
   break;
  unitmask = unitmask >> 1;
 }

 return (i + 'A');
}
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPSTR lpCmdLine, int nCmdShow )
{
        DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN),
                  hWnd, DlgProc);

  return 0;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    hFileList = GetDlgItem(hWndDlg,IDC_FILE_LIST);
    hDstDir = GetDlgItem(hWndDlg,IDC_DST_DIR);
    hLog = GetDlgItem(hWndDlg,IDC_LOG);
    hBtnSave = GetDlgItem(hWndDlg,IDC_BTN_SAVE);
    hBtnBrowse = GetDlgItem(hWndDlg,IDC_BTN_BROWSE);
    switch(Msg)
    {
    case WM_INITDIALOG:
        //icon setting
        hIcon = (HICON)LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ICON4));
        SendMessage(hWndDlg, WM_SETICON, ICON_BIG  , (LPARAM)hIcon);
        hIconSm = (HICON)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON4));
        SendMessage(hWndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
        //read config file , if not exist, create a new one
        SetWindowText(hFileList,ReadConfigFile("filelist"));
        SetWindowText(hDstDir,ReadConfigFile("dstdir"));
        SetWindowText(hLog,"#等待设备...\r\n");
        return TRUE;

    case WM_DEVICECHANGE:
        dhr   =   (DEV_BROADCAST_HDR   *)lParam;
        switch(wParam)
        {
        case DBT_CONFIGCHANGECANCELED:
            return 0;
        case DBT_DEVICEARRIVAL:
            if(dhr->dbch_devicetype == DBT_DEVTYP_VOLUME)
            {
                lpdbv = (PDEV_BROADCAST_VOLUME)dhr;
                if(lpdbv->dbcv_flags  == 0)
                {
                    //sprintf(buf,"%c",FirstDriveFromMask(lpdbv->dbcv_unitmask));
                    pArgs arg;
                    arg = malloc(sizeof(struct ArgsTag));
                    GetWindowText(hLog,buf2,sizeof(buf2));
                    arg->vol= FirstDriveFromMask(lpdbv->dbcv_unitmask);
                    arg->hWndDlg = hWndDlg;
                    wsprintf(subStr,"#检测盘符...【%c】盘\r\n",arg->vol);
                    strcat(buf2,subStr);
                    SetWindowText(hLog,buf2);
                    Sleep(1000);
                    //UsbCopyFile(ReadConfigFile("filelist"),ReadConfigFile("dstdir"), vol);
                    _beginthread ((LPVOID)CopyThread, 0, (LPVOID)arg) ;
                }
            }
            return 0;
        }
        break;
    case WM_COMMAND:
            switch(LOWORD(wParam))
            {
            case IDC_FILE_LIST:
                if(HIWORD(wParam) == EN_CHANGE)
                {
                    EnableWindow(hBtnSave,TRUE);
                }
                return TRUE;
            case IDC_DST_DIR:
                if(HIWORD(wParam) == EN_CHANGE)
                {
                    EnableWindow(hBtnSave,TRUE);
                }
                return TRUE;
            case IDCANCEL:
                EndDialog(hWndDlg, 0);
                return TRUE;
            case IDC_BTN_SAVE:
                //content of file list
                /*
                i = HIWORD(wParam);
                i = LOWORD(wParam);
                i = lParam;
                */
                GetWindowText(hFileList,bufFileList,sizeof(bufFileList)/sizeof(TCHAR));
                GetWindowText(hDstDir,bufDstDir,sizeof(bufDstDir)/sizeof(TCHAR));
                //write config
                WriteConfigFile(bufFileList,bufDstDir);
                EnableWindow(hBtnSave,FALSE);
                return TRUE;
            case IDC_BTN_BROWSE:
                //ZeroMemory(szPath, sizeof(szPath));
                ZeroMemory(&bi,sizeof(BROWSEINFO));
                bi.hwndOwner    = NULL;                          //HWND句柄
                bi.pidlRoot       = NULL;                          //默认值为NULL
                bi.lpszTitle       = ("文件浏览对话框");          //对话框标题
                bi.pszDisplayName = szPath;                          //选择文件夹路径
                bi.ulFlags        = BIF_RETURNONLYFSDIRS;       //标记
                bi.lpfn           = NULL;                          //默认值为NULL
                bi.lParam         = 0;                          //回调消息
                lpItemIdList = SHBrowseForFolder(&bi);  //显示文件浏览对话框
                if(SHGetPathFromIDList(lpItemIdList,szPath))
                    SetWindowText(hDstDir,szPath);
                return TRUE;

            }
            break;
    }//end of Msg
    return FALSE;
}
//---------------------------------------------------------------------------

RESOURCE.H

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by UsbAutoCopy.rc
//
#define IDD_MAIN                        101
#define IDI_ICON1                       102
#define IDI_ICON2                       103
#define IDI_ICON3                       104
#define IDI_ICON4                       110
#define IDC_EDIT1                       1000
#define IDC_FILE_LIST                   1000
#define IDC_EDIT2                       1001
#define IDC_LOG                         1001
#define IDC_EDIT3                       1002
#define IDC_DST_DIR                     1002
#define IDC_BUTTON1                     1003
#define IDC_BTN_BROWSE                  1003
#define IDC_BUTTON2                     1004
#define IDC_BTN_SAVE                    1004

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        111
#define _APS_NEXT_COMMAND_VALUE         40002
#define _APS_NEXT_CONTROL_VALUE         1005
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

UsbAutoCopy.rc :资源脚本

//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// Chinese (P.R.C.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_MAIN DIALOG DISCARDABLE  200, 150, 449, 271
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | 
    WS_CAPTION | WS_SYSMENU
CAPTION "USB AutoCopy"
FONT 8, "MS Sans Serif"
BEGIN
    GROUPBOX        "设置",IDC_STATIC,8,8,181,255
    GROUPBOX        "日志",IDC_STATIC,201,8,240,255
    EDITTEXT        IDC_FILE_LIST,18,37,160,134,ES_MULTILINE | 
                    ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER
    EDITTEXT        IDC_LOG,213,25,220,227,ES_MULTILINE | ES_AUTOVSCROLL | 
                    ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER | 
                    WS_VSCROLL | WS_HSCROLL
    EDITTEXT        IDC_DST_DIR,18,198,110,14,ES_AUTOHSCROLL | ES_READONLY
    PUSHBUTTON      "浏览",IDC_BTN_BROWSE,128,198,50,14
    PUSHBUTTON      "保存设置",IDC_BTN_SAVE,21,234,147,20
    CONTROL         "文件列表",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | 
                    WS_GROUP,18,25,160,8
    LTEXT           "复制到目录",IDC_STATIC,18,185,110,8
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE 
BEGIN
    IDD_MAIN, DIALOG
    BEGIN
        LEFTMARGIN, 8
        RIGHTMARGIN, 441
        TOPMARGIN, 8
        BOTTOMMARGIN, 263
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON4               ICON    DISCARDABLE     "Device-USB.ico"
#endif    // Chinese (P.R.C.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

2 个答案:

答案 0 :(得分:1)

现在您已经更新了代码,问题就更清晰了:

arg = malloc(sizeof(args));

表示分配了sizeof(args)。由于您将args作为指针键入struct args,这意味着只分配了4个字节(假设为32位)。这对于s​​truct的第一个字段就足够了,但是当你这样做时:

arg->hWndDlg = hWndDlg;

你写的超出了分配的记忆,在某些人的土地上。

要解决您的问题,您应该使用malloc(sizeof(struct args)),它是sizeof(CHAR)+ sizeof(HWND),而不是sizeof(struct args *)。或者,更好的是,更改你的typedef,以减少错误,例如:

typedef struct ArgsTag {
    CHAR vol;
    HWND hWndDlg;
} Args, *ArgsPtr;

左右,然后使用Args进行分配,使用ArgsPtr进行访问。

答案 1 :(得分:0)

如果你得到正确的卷,那么这意味着你至少部分地正确地初始化结构。检查以确保您复制的HWND与实际HWND相同。如果您正在创建无模式对话框,则返回为HWND。如果你正在创建一个模态,那么你可以使用DialogBoxParam()传入指向结构的指针,然后可以在WM_INITDIALOG中初始化。