2007年12月11日星期二

发送button Onclick 消息

GetDlgItem(IDC_BUTTON_ROLLBACK)->PostMessage( WM_LBUTTONDOWN,BM_CLICK,0);
GetDlgItem(IDC_BUTTON_ROLLBACK)->PostMessage( WM_LBUTTONUP, BM_CLICK,0);

改变窗口标题

调用CWnd : : SetWindowText可以改变任何窗口(包括控件)的标题。

//Set title for application's main frame window .
AfxGetMainWnd ( ) —> SetWindowText (_T("Application title") );

//Set title for View's MDI child frame window .
GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame new title") );

//Set title for dialog's push button control.
GetDigitem (IDC_BUTTON) —> SetWindowText (_T ("Button new title ") );

如果需要经常修改窗口的标题(注:控件也是窗口),应该考虑使用半文档化的函数AfxSetWindowText。该函数在AFXPRIV.H中说明,在WINUTIL.CPP中实现,在联机帮助中找不到它,它在AFXPRIV.H中半文档化, 在以后发行的MFC中将文档化。

AfxSetWindowText的实现如下:

voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew )
{
itn nNewLen= Istrlen (Ipaznew);
TCHAR szOld [256];
//fast check to see if text really changes (reduces flash in the controls )
if (nNewLen >_contof (szOld) ||::GetWindowText (hWndCrtl , szOld , _countof (szOld) !=nNewLen ||Istrcmp (szOld , IpszNew )! = 0
{
//change it
::SetWindowText (hWndCtrl , IpszNew );
}
}

2007年12月10日星期一

调出主窗口

AfxGetMainWnd();//调出主窗口

2007年12月7日星期五

CreateThread

例1:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char a[255];
strcpy(a,"qinwei");
DWORD dwThreadId;
CreateThread(NULL,0,ClientThread,(LPVOID)a,0,&dwThreadId);
}
DWORD WINAPI ClientThread(LPVOID lpParam)
{
char* a = (char* )lpParam;
ShowMessage(a);// <------------通过
return 0;
}

例2:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
POINT a;
DWORD dwThreadId;
a.x=7;
CreateThread(NULL,0,ClientThread,(LPVOID)&a,0,&dwThreadId);
}
DWORD WINAPI ClientThread(LPVOID lpParam)
{
POINT* a = (POINT* )lpParam;
ShowMessage(a->x);// <------------出错
return 0;
}

2007年12月6日星期四

几种控件的绑定

m_pListCt->pList = (CListCtrl*) GetDlgItem(IDC_LIST_DB);

if(!m_pListCt->pList->m_hWnd) //check if the ColorListstyle was already assigned
m_pListCt->pList->SubclassDlgItem(IDC_LIST_DB,this);

//hide the button:
GetDlgItem(IDC_BUTTON_ROLLBACK)->EnableWindow(false);

2007年12月5日星期三

CreateProcess 能够返回错误码

STARTUPINFO si = { sizeof(STARTUPINFO) };

si.dwFlags = STARTF_USESHOWWINDOW;

si.wShowWindow = SW_HIDE;

PROCESS_INFORMATION pi;

CreateProcess(NULL, _T("app.exe"), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

if (showwait)
{
while( WaitForSingleObject(pi.hProcess, 5000)!=WAIT_OBJECT_0 )
{
if ( str.Find(_T("tool")) == -1 ) //str is not the execution of tool -wait
{
WinExec(CPublic::tool + "-wait4",SW_SHOWNORMAL);
}
}
}
else
{
WaitForSingleObject(pi.hProcess, INFINITE);
}

DWORD exit_code;

GetExitCodeProcess(pi.hProcess, &exit_code);

// TODO: check for errors

// TODO: free handles

我的代码:

BOOL CPublic::ProcessFiles(CString App, CString Command, BOOL showwait)
{
BOOL bProcess = false;
try
{
LPCTSTR lpApplicationName = NULL;
LPTSTR lpCommandLine;

Command = (LPCTSTR)(App + CString(" ") + Command);
//lpApplicationName = "\"" +App +"\"";
lpCommandLine = (char*)(LPCSTR) Command;

//TCHAR * lpCommandLine = new TCHAR();
//lpCommandLine = _tcsdup(TEXT("\"" +App + "\" " + Command));

STARTUPINFO si = { sizeof(STARTUPINFO) };

si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;

PROCESS_INFORMATION pi;

CreateProcess(lpApplicationName, lpCommandLine, NULL, NULL, FALSE, 0, NULL, (LPCTSTR)InstallDir, &si, &pi);
//CString str = GetCommandLine();
//AfxMessageBox(str);
if (showwait)
{
while( WaitForSingleObject(pi.hProcess, 5000)!=WAIT_OBJECT_0 )
{
if ( App.Find(_T("tool")) == -1 ) //str is not the execution of tool -wait
{
CPublic::ProcessMessages();
WinExec((LPCTSTR)(tool + CString("-wait4")),SW_SHOWNORMAL);
CPublic::ProcessMessages();

}

}

}
else
{
//WaitForSingleObject(pi.hProcess, INFINITE);
while( WaitForSingleObject(pi.hProcess, 500)!=WAIT_OBJECT_0 )
{
CPublic::ProcessMessages();


}

}
CPublic::ProcessMessages();
DWORD exit_code;

if ( GetExitCodeProcess(pi.hProcess, &exit_code) )
bProcess = true;


////////////////////////////////////////////////////////////////
//
// * edit by zengzn@gamil.com on 11.04.2008
//
// * "exit_code" is now known:
// 0: application success ran in win.
// 10: application terminates itself.
// 1: user terminate the process.
// ....
// * so we can judge that if a process was crashed or killed
// by user or self terminated
//
////////////////////////////////////////////////////////////////
//CString s;
//s.Format("%d",exit_code);
//AfxMessageBox(s);

if (exit_code != 10 && exit_code != 0)
bProcess = false;


// TODO: free handles

}catch(CException &e){
CString sMeldungsText;
char sErrorText[256];
e.GetErrorMessage(sErrorText,255);
sMeldungsText.Format("%s: %s%s","ProcessFiles()","ATAGAB/AKASSE -MakeTagab: Es kam zu einem allgemeinen Fehler at: ",sErrorText);
AfxMessageBox((LPCTSTR)sMeldungsText);

}
return bProcess;

}

MFC中窗体的控制

1、在CMainFrame的PreCreateWindow(CREATESTRUCT& cs)函数中,加入:
cs.cx=300;
cs.cy=400;
即可控制窗体初始化时的大小。

2、加入这段代码可以设置一个没有“最小化”按钮和“最大化”按钮,也没有大小可调边框的主框架窗口。此窗口最初在屏幕上居中。
cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER;
// Size the window to 1/3 screen size and center it
cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3;
cs.y = cs.cy;// ((cs.cy * 3) - cs.cy) / 2;
cs.x = cs.cx;//((cs.cx * 3) - cs.cx) / 2;

3、如果要在创建窗体前设置标题,需加入一下两行:
cs.style &= ~FWS_ADDTOTITLE; //如果style中已经有WS_OVERLAPPED,如上例,就已经包含了~FWS_ADDTOTITLE项;
cs.lpszName = "http://www.icafe8.net";

4、如果在窗体创建时改变窗体的一些属性,可以用SetWindowLong()函数,如:
SetWindowLong(m_hWnd,GWL_STYLE, GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX); //先获取窗体的类型,然后禁用最大化按钮。

5、创建一个窗体:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_HELP);
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wndcls.hInstance=AfxGetInstanceHandle();
wndcls.lpfnWndProc=::DefWindowProc;
wndcls.lpszClassName="limeng's window";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls); //将窗体注册到类
cs.lpszClass="limeng's window"; //这里的名字必须和上面创建的wndcls类的名字相同
return TRUE;
}
注意:上面的代码只写在MainFrame中,必须在View窗体中增加最后一行,否则将无法看到效果,因为View窗体始终覆盖在Main窗体之上。

6、如果觉得上面的方法太烦,我们可以通过AfxRegisterWndClass函数简单的改变一个窗体的样式:
可以在MainFrame的PreCreateWindow中加入:
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING)); //因为在框架中设置鼠标和底色是无法体现的,所以设置为0。
在View的PreCreateWindow中加入:
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, LoadCursor(NULL,IDC_HELP),(HBRUSH)GetStockObject(DKGRAY_BRUSH), 0);//而在View窗体中,图表设置又是无效的,所以为0

7、有意思的的是,如果在Main和View的PreCreateWindow中用默认的参数注册窗口:
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
结果,鼠标是默认的箭头鼠标,图标为window默认的波浪图标,但是窗口因为是空的画刷,所以你可以看到一个透明的窗口,但是你拖动窗体时,窗体不会重绘,所以能保持刚才的背景图画,除非窗体被重画的动作发生,如最小化,或别的窗体在此窗体的顶部停留。

8、这里我们可以通过SetClassLong对窗体的单个属性进行设置。
在main框架函数的OnCreate函数中写入:
SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_WARNING));//设置窗体的图标为IDI_ERROR
右键点View窗体类,增加一个WM_CREATE消息相应函数,在View窗体的OnCreate函数中写入:
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(DKGRAY_BRUSH));//设置背景为灰色
SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));//设置鼠标为help类型
便可以得到如6中相同的效果。

9、接下来我们试着设计一个程序,让他在3个图标中每秒切换一个。
首先我们在插入资源中,导入3张.ico的图片,资源ID号分别为IDI_ICON1,IDI_ICON2,IDI_ICON3。然后在MainFrame中添加一个数组成员变量:
private:
HICON m_hIcons[3];
在MainFrame的OnCreate函数中,将icon加载进来:
m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1)); /*方法一,通过全局函数直接获得当前实例的句柄,然后直接将图标的ID号转换为资源名称。*/
m_hIcons [1]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2)); /*方法二,利用 CWinApp派生的App类中。注意要在函数前面申明引用外部变量extern CStyleApp theApp。*/
m_hIcons[2]=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3)); /*方法三,通过获得应用程序的成员变量。*/
SetTimer(1,1000,NULL); //设置一个每1秒钟触发一次的OnTimer事件
在MainFrame中增加一个OnTimer的Windows消息相应函数:
static int index=0; //注意用静态变量,否则会被每次调用OnTimer事件时初始化为0。
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[index]);
index=++index%3; //取模,让index限定在0-2之间。