关于MFC多线程中对控件变量的访问问题

时间:2021-07-18 18:05:48
小弟今日写一漏洞扫描的课设,在利用MFC设计界面中遇到一个小问题,恳求大家帮忙出出主意。
我利用createThread创建了一个线程,当然啦,主线程肯定是用来绘图的,然后创建的线程里面主要就是各种扫描函数(端口扫描,服务器扫描),但是在创建的线程中我要将扫描过程中一步步的结果显示到屏幕上去,这就自己写了一个函数Chole30Dlg::ScanSendMeg(CString TempBuf),它的作用就是将TempBuf中的内容送到指定地方,具体如下:
bool Chole30Dlg::ScanSendMeg(CString TempBuf)
{
CString strTemp;
Chole30Dlg::FindWindow(NULL,"hole3.0")->GetDlgItemTextA(IDC_SCANPROC,strTemp);
strTemp+="\r\n";
strTemp+=TempBuf;
Chole30Dlg::FindWindow(NULL,"hole3.0")->SetDlgItemTextA(IDC_SCANPROC,strTemp);
Chole30Dlg::m_ScanResult.LineScroll(Chole30Dlg::m_ScanResult.GetLineCount());//此处出错了。。。error C2228: “.LineScroll”的左边必须有类/结构/联合
1>g:\mfc\hole4.0\hole3.0\hole3.0dlg.cpp(628) : error C2228: “.GetLineCount”的左边必须有类/结构/联合。。。m_ScanResult为一个关联的一个CEDIT控件变量
return true;
}
上面的函数是在创建的线程中被反复调用。。。。
我知道在创建线程时可以把对话框的指针传进去这样就可以在线程中去对对话框发送消息了,可是没有相关的实例,我悟性不佳,恳求大家帮个忙,看看怎么解决哈,有什么不明白的我回来尽快回复,谢谢~

12 个解决方案

#1


光看报错楼主
m_ScanResult是指针的样子


m_ScanResult->GetLineCount()
看看

#2


To tiger9991:
我改为->还是不行的。。m_ScanResult是对话框中上编辑框对应的控件变量,上述代码是实现将扫描线程中执行的结果输出到编辑框中,这个函数在扫描线程中被各扫描的函数调用来输出文本Chole30Dlg::m_ScanResult.LineScroll(Chole30Dlg::m_ScanResult.GetLineCount());//此处出错了。。。这一句本想是用来使编辑框右边的垂直滚动条能自动根据文本移动到最下面。可是这个小问题一直纠结着我。。查了一些资料,希望大家给点建议,不胜感激

#3


知道在创建线程时可以把对话框的指针传进去这样就可以在线程中去对对话框发送消息了,

你知道的是错误的

句柄!

#4


上传下代码看下吧。

不明白为啥都加

Chole30Dlg::

#5


需要想办法获取到对象m_ScanResult,而不是直接用类

#6


明确了一下问题:
(1)你是想让Edit实时显示到最后添加文字的区域,也就是你说的滚动条自动滚动到那里。一般是这样做的:

CString str;
m_ScanResult.GetWindowText(str);
m_ScanResult.SetSel(str.GetLength(),str.GetLength());

(2)你直接用类名调用Chole30Dlg::m_ScanResult是不正确的。你可以直接写this->m_ScanResult.

#7


#include "stdafx.h"
#include "hole3.0.h"
#include "hole3.0Dlg.h"
#include "IPExpDlg.h"
#include "windows.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// 对话框数据
enum { IDD = IDD_ABOUTBOX };

protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// Chole30Dlg 对话框


char *Chole30Dlg::DestIPAddr=new char[16];//扫描主机IP
int *Chole30Dlg::PortRag=new int[11];//扫描端口
int *Chole30Dlg::intFlagSave=new int(1);
int *Chole30Dlg::portScanFlag=new int(1);
Chole30Dlg::Chole30Dlg(CWnd* pParent /*=NULL*/)
: CDialog(Chole30Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
for(int flag=0;flag<11;flag++)
{
Chole30Dlg::PortRag[flag]=80+flag;
}
*intFlagSave=0;
*portScanFlag=0;
}

void Chole30Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_IPADDRESS1, m_IP);
DDX_Control(pDX, IDC_SCANPROC, m_ScanResult);
}

BEGIN_MESSAGE_MAP(Chole30Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_IPEXP, &Chole30Dlg::OnBnClickedIpexp)
ON_BN_CLICKED(IDC_AUTOSCAN, &Chole30Dlg::OnBnClickedAutoscan)
ON_BN_CLICKED(IDC_QUIT, &Chole30Dlg::OnBnClickedQuit)
ON_BN_CLICKED(IDC_SAVE, &Chole30Dlg::OnBnClickedSave)
ON_BN_CLICKED(IDC_RETURN, &Chole30Dlg::OnBnClickedReturn)
ON_BN_CLICKED(IDC_SELFSCAN, &Chole30Dlg::OnBnClickedSelfscan)
END_MESSAGE_MAP()


// Chole30Dlg 消息处理程序

BOOL Chole30Dlg::OnInitDialog()
{
CDialog::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码
Chole30Dlg::PreScan();
HANDLE hThread=CreateThread(NULL,0,PortProc,NULL,0,NULL);
CloseHandle(hThread);//重点。。创建了扫描线程
return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void Chole30Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else if ((nID & 0xfff0) == SC_CLOSE)
{
if(MessageBox("确定退出?","退出" ,MB_ICONEXCLAMATION|MB_OKCANCEL)==IDCANCEL)
return;
else
exit(0);
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void Chole30Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
//CDialog::OnPaint();
 CPaintDC   dc(this);   
         CRect   rect;   
         GetClientRect(&rect);   
         CDC   dcMem;   
         dcMem.CreateCompatibleDC(&dc);   
         CBitmap   bmpBackground;   
         bmpBackground.LoadBitmap(IDB_BITMAP_GRUND); 
 BITMAP   bitmap;   
         bmpBackground.GetBitmap(&bitmap);   
         CBitmap *pbmpOld=dcMem.SelectObject(&bmpBackground);   
         dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,   
         bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);

}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR Chole30Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}


void Chole30Dlg::OnBnClickedIpexp()
{
// TODO: 在此添加控件通知处理程序代码
CIPExpDlg CIPExpDlging;
CIPExpDlging.DoModal();
}

void Chole30Dlg::OnBnClickedAutoscan()
{
// TODO: 在此添加控件通知处理程序代码
BYTE f0, f1, f2, f3; 
m_IP.GetAddress(f0, f1, f2, f3);
        CString m_addr; 
        m_addr.Format("%d%s%d%s%d%s%d", f0, ".", f1, ".", f2, ".", f3); 
strcpy(DestIPAddr,m_addr);
if(strcmp("0.0.0.0",DestIPAddr)==0)
{
MessageBox("IP输入有误!");
}
else
{
Chole30Dlg::AutoScanDraw();//为开始扫描前的界面做一些处理
*portScanFlag=1;//此处标志位被改变,另外一个线程在获得时间片后可以进行扫描了
}
}

int Chole30Dlg::start(void)
{
//这个里面就是端口扫描的程序,在程序里面多次会用到ScanSendMeg()函数来将扫描得到的一步步结果放到屏幕上去,代码很长,我想大家可能会看的头疼所以没贴。。。
}


bool Chole30Dlg::ScanSendMeg(CString TempBuf)
{
CString strTemp;
Chole30Dlg::FindWindow(NULL,"hole3.0")->GetDlgItemTextA(IDC_SCANPROC,strTemp);
strTemp+="\r\n";
strTemp+=TempBuf;
Chole30Dlg::FindWindow(NULL,"hole3.0")->SetDlgItemTextA(IDC_SCANPROC,strTemp);
Chole30Dlg::m_ScanResult.LineScroll(Chole30Dlg::m_ScanResult->GetLineCount());//这里出错
return true;
}

void Chole30Dlg::OnBnClickedQuit()
{
//这个里面是退出并保存事件处理程序,已实现
}

void Chole30Dlg::OnBnClickedSave()
{
// TODO: 在此添加控件通知处理程序代码
Chole30Dlg::SaveRep();//保存按钮事件处理程序,已实现
}
void Chole30Dlg::SaveRep(void)
{
//保存程序,已实现
}

DWORD WINAPI Chole30Dlg::PortProc(LPVOID lpParam)
{//重点就是这里,这个函数就是创建的新线程的入口函数
while(true)
{
if(*portScanFlag==0)/*一直循环,直到这个标志位被改变,也就是用户点击了开始之后才会真正地调用start()和Ftp()来扫描,这个地方最好是用挂起和唤醒线程来操作吧?我暂时先这么处理着,后面再完善*/
continue;
else
{
Chole30Dlg::start();//调用扫描函数
Chole30Dlg::Ftp();
return 0;
}
}
}

void Chole30Dlg::OnBnClickedSelfscan()
{
// TODO: 在此添加控件通知处理程序代码
Chole30Dlg::KeyScanDraw();
}

int Chole30Dlg::Ftp(void)
{
//这个里面是FTP扫描,代码太长,可以实现了,我就不贴了
}

To tiger9991:这个是Chole30Dlg.cpp文件里面的主要代码。。我知道看别人的代码是一件痛苦的事情,尤其是看我这种没什么条理的代码。谢谢大家了。这个是我用来调试的版本代码,我把扫描的函数和界面的函数都放一起了。在一切实现以后肯定会将他们分开来写。。
To #3:谢谢你的提醒,在c和c++里面我弄乱了,我一直把指针,引用以及句柄还有一些东西乱了。。要好好看下。
To #5:你说到我的痛处了。。。。我也想获得关于这个对话框的对象,可是这个对话框就是基于对话框建立的,我不知道如何取获得这个对象。。获得句柄可以么?我不知道如何获得这个对话框的对象,所以才将大部分函数声明为静态成员函数的。。。恳请指点一下。。
To #6:我的目的确实是你说的那样,可是在另外创建的线程中我这样去做就错了。。。this->m_ScanResult这样还是报错了。。我想这个可能是跟我创建的线程有关吧,我没把对话框句柄传进来,谢谢你了

#8


建议你使用往你的Dialog发消息的方式将数据传递过去,在对话框的响应函数里处理和显示。

另:跨线程访问窗口对象是不安全的,微软对此有说明

#9


对了,程序运行时内存占用不大,但是cpu随着程序反复执行其利用率会达到100%,这。。。怎么办。。

#10


PortProc是静态的。
改为:
((Chole30Dlg*)(AfxGetApp()->GetMainWnd()))->m_ScanResult.GetLineCount();

最好用消息的那样

#11


楼主,记得在创建线程的时候,将要传入的数据传入进去,查查MSDN 你应该就懂了

#12


楼主可以通过自定义消息的形式把扫描结果传递给主窗口。在创建线程的时候把窗口的指针作为参数。然后在线程函数开头直接用一个普通的CWnd *pWnd=(CWnd *)lpParam;就可以传递消息。
传递方法:先定义一个自定义消息宏,比如#define WM_MY_MSG WM_USER+100
接着重载主窗口的虚函数OnWndMsg
最后,在线程函数中要发送消息的地方,调用pWnd->SendMessage(WM_MY_MSG,...,...);后面2个参数可以是指针也可以是一个普通的数值型变量,把要传递的数据或者其指针做参数就能传递数据了。这样主窗口的OnWndMsg会响应,在这里把得到的数据放到窗口中吧

#1


光看报错楼主
m_ScanResult是指针的样子


m_ScanResult->GetLineCount()
看看

#2


To tiger9991:
我改为->还是不行的。。m_ScanResult是对话框中上编辑框对应的控件变量,上述代码是实现将扫描线程中执行的结果输出到编辑框中,这个函数在扫描线程中被各扫描的函数调用来输出文本Chole30Dlg::m_ScanResult.LineScroll(Chole30Dlg::m_ScanResult.GetLineCount());//此处出错了。。。这一句本想是用来使编辑框右边的垂直滚动条能自动根据文本移动到最下面。可是这个小问题一直纠结着我。。查了一些资料,希望大家给点建议,不胜感激

#3


知道在创建线程时可以把对话框的指针传进去这样就可以在线程中去对对话框发送消息了,

你知道的是错误的

句柄!

#4


上传下代码看下吧。

不明白为啥都加

Chole30Dlg::

#5


需要想办法获取到对象m_ScanResult,而不是直接用类

#6


明确了一下问题:
(1)你是想让Edit实时显示到最后添加文字的区域,也就是你说的滚动条自动滚动到那里。一般是这样做的:

CString str;
m_ScanResult.GetWindowText(str);
m_ScanResult.SetSel(str.GetLength(),str.GetLength());

(2)你直接用类名调用Chole30Dlg::m_ScanResult是不正确的。你可以直接写this->m_ScanResult.

#7


#include "stdafx.h"
#include "hole3.0.h"
#include "hole3.0Dlg.h"
#include "IPExpDlg.h"
#include "windows.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// 对话框数据
enum { IDD = IDD_ABOUTBOX };

protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// Chole30Dlg 对话框


char *Chole30Dlg::DestIPAddr=new char[16];//扫描主机IP
int *Chole30Dlg::PortRag=new int[11];//扫描端口
int *Chole30Dlg::intFlagSave=new int(1);
int *Chole30Dlg::portScanFlag=new int(1);
Chole30Dlg::Chole30Dlg(CWnd* pParent /*=NULL*/)
: CDialog(Chole30Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
for(int flag=0;flag<11;flag++)
{
Chole30Dlg::PortRag[flag]=80+flag;
}
*intFlagSave=0;
*portScanFlag=0;
}

void Chole30Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_IPADDRESS1, m_IP);
DDX_Control(pDX, IDC_SCANPROC, m_ScanResult);
}

BEGIN_MESSAGE_MAP(Chole30Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_IPEXP, &Chole30Dlg::OnBnClickedIpexp)
ON_BN_CLICKED(IDC_AUTOSCAN, &Chole30Dlg::OnBnClickedAutoscan)
ON_BN_CLICKED(IDC_QUIT, &Chole30Dlg::OnBnClickedQuit)
ON_BN_CLICKED(IDC_SAVE, &Chole30Dlg::OnBnClickedSave)
ON_BN_CLICKED(IDC_RETURN, &Chole30Dlg::OnBnClickedReturn)
ON_BN_CLICKED(IDC_SELFSCAN, &Chole30Dlg::OnBnClickedSelfscan)
END_MESSAGE_MAP()


// Chole30Dlg 消息处理程序

BOOL Chole30Dlg::OnInitDialog()
{
CDialog::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码
Chole30Dlg::PreScan();
HANDLE hThread=CreateThread(NULL,0,PortProc,NULL,0,NULL);
CloseHandle(hThread);//重点。。创建了扫描线程
return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void Chole30Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else if ((nID & 0xfff0) == SC_CLOSE)
{
if(MessageBox("确定退出?","退出" ,MB_ICONEXCLAMATION|MB_OKCANCEL)==IDCANCEL)
return;
else
exit(0);
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void Chole30Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
//CDialog::OnPaint();
 CPaintDC   dc(this);   
         CRect   rect;   
         GetClientRect(&rect);   
         CDC   dcMem;   
         dcMem.CreateCompatibleDC(&dc);   
         CBitmap   bmpBackground;   
         bmpBackground.LoadBitmap(IDB_BITMAP_GRUND); 
 BITMAP   bitmap;   
         bmpBackground.GetBitmap(&bitmap);   
         CBitmap *pbmpOld=dcMem.SelectObject(&bmpBackground);   
         dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,   
         bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);

}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR Chole30Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}


void Chole30Dlg::OnBnClickedIpexp()
{
// TODO: 在此添加控件通知处理程序代码
CIPExpDlg CIPExpDlging;
CIPExpDlging.DoModal();
}

void Chole30Dlg::OnBnClickedAutoscan()
{
// TODO: 在此添加控件通知处理程序代码
BYTE f0, f1, f2, f3; 
m_IP.GetAddress(f0, f1, f2, f3);
        CString m_addr; 
        m_addr.Format("%d%s%d%s%d%s%d", f0, ".", f1, ".", f2, ".", f3); 
strcpy(DestIPAddr,m_addr);
if(strcmp("0.0.0.0",DestIPAddr)==0)
{
MessageBox("IP输入有误!");
}
else
{
Chole30Dlg::AutoScanDraw();//为开始扫描前的界面做一些处理
*portScanFlag=1;//此处标志位被改变,另外一个线程在获得时间片后可以进行扫描了
}
}

int Chole30Dlg::start(void)
{
//这个里面就是端口扫描的程序,在程序里面多次会用到ScanSendMeg()函数来将扫描得到的一步步结果放到屏幕上去,代码很长,我想大家可能会看的头疼所以没贴。。。
}


bool Chole30Dlg::ScanSendMeg(CString TempBuf)
{
CString strTemp;
Chole30Dlg::FindWindow(NULL,"hole3.0")->GetDlgItemTextA(IDC_SCANPROC,strTemp);
strTemp+="\r\n";
strTemp+=TempBuf;
Chole30Dlg::FindWindow(NULL,"hole3.0")->SetDlgItemTextA(IDC_SCANPROC,strTemp);
Chole30Dlg::m_ScanResult.LineScroll(Chole30Dlg::m_ScanResult->GetLineCount());//这里出错
return true;
}

void Chole30Dlg::OnBnClickedQuit()
{
//这个里面是退出并保存事件处理程序,已实现
}

void Chole30Dlg::OnBnClickedSave()
{
// TODO: 在此添加控件通知处理程序代码
Chole30Dlg::SaveRep();//保存按钮事件处理程序,已实现
}
void Chole30Dlg::SaveRep(void)
{
//保存程序,已实现
}

DWORD WINAPI Chole30Dlg::PortProc(LPVOID lpParam)
{//重点就是这里,这个函数就是创建的新线程的入口函数
while(true)
{
if(*portScanFlag==0)/*一直循环,直到这个标志位被改变,也就是用户点击了开始之后才会真正地调用start()和Ftp()来扫描,这个地方最好是用挂起和唤醒线程来操作吧?我暂时先这么处理着,后面再完善*/
continue;
else
{
Chole30Dlg::start();//调用扫描函数
Chole30Dlg::Ftp();
return 0;
}
}
}

void Chole30Dlg::OnBnClickedSelfscan()
{
// TODO: 在此添加控件通知处理程序代码
Chole30Dlg::KeyScanDraw();
}

int Chole30Dlg::Ftp(void)
{
//这个里面是FTP扫描,代码太长,可以实现了,我就不贴了
}

To tiger9991:这个是Chole30Dlg.cpp文件里面的主要代码。。我知道看别人的代码是一件痛苦的事情,尤其是看我这种没什么条理的代码。谢谢大家了。这个是我用来调试的版本代码,我把扫描的函数和界面的函数都放一起了。在一切实现以后肯定会将他们分开来写。。
To #3:谢谢你的提醒,在c和c++里面我弄乱了,我一直把指针,引用以及句柄还有一些东西乱了。。要好好看下。
To #5:你说到我的痛处了。。。。我也想获得关于这个对话框的对象,可是这个对话框就是基于对话框建立的,我不知道如何取获得这个对象。。获得句柄可以么?我不知道如何获得这个对话框的对象,所以才将大部分函数声明为静态成员函数的。。。恳请指点一下。。
To #6:我的目的确实是你说的那样,可是在另外创建的线程中我这样去做就错了。。。this->m_ScanResult这样还是报错了。。我想这个可能是跟我创建的线程有关吧,我没把对话框句柄传进来,谢谢你了

#8


建议你使用往你的Dialog发消息的方式将数据传递过去,在对话框的响应函数里处理和显示。

另:跨线程访问窗口对象是不安全的,微软对此有说明

#9


对了,程序运行时内存占用不大,但是cpu随着程序反复执行其利用率会达到100%,这。。。怎么办。。

#10


PortProc是静态的。
改为:
((Chole30Dlg*)(AfxGetApp()->GetMainWnd()))->m_ScanResult.GetLineCount();

最好用消息的那样

#11


楼主,记得在创建线程的时候,将要传入的数据传入进去,查查MSDN 你应该就懂了

#12


楼主可以通过自定义消息的形式把扫描结果传递给主窗口。在创建线程的时候把窗口的指针作为参数。然后在线程函数开头直接用一个普通的CWnd *pWnd=(CWnd *)lpParam;就可以传递消息。
传递方法:先定义一个自定义消息宏,比如#define WM_MY_MSG WM_USER+100
接着重载主窗口的虚函数OnWndMsg
最后,在线程函数中要发送消息的地方,调用pWnd->SendMessage(WM_MY_MSG,...,...);后面2个参数可以是指针也可以是一个普通的数值型变量,把要传递的数据或者其指针做参数就能传递数据了。这样主窗口的OnWndMsg会响应,在这里把得到的数据放到窗口中吧