2007年12月20日星期四

获得Cxxxview指针

前提: 在要获得view指针的.cpp文档中加入view.h及其头文档:
//----include header for CDbinfoView *pView
#include "ColorEdit.h"
#include "ColorStatic.h"
#include "ListCtrlStyled.h"
#include "DBinfoReg.h"
#include "dbinfo.h"
#include "dbinfoSet.h"
#include "ADOpaelogbuch.h"
#include "ABBruchDialog.h"
#include "DBinfoSmall.h"
#include "DBinfoListCt.h"
#include "dbinfoDoc.h"
#include "dbinfoView.h"
//----include header for CDbinfoView *pView

获得view指针:
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;

// Get the active MDI child window.
CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();

// or CMDIChildWnd *pChild = pFrame->MDIGetActive();

// Get the active view attached to the active MDI child window.
CDbinfoView *pView = (CDbinfoView *) pChild->GetActiveView();


参考:
在MFC类中各种类的指针的获取和应用

取得文件的 Version information

连接库函数:
//----add by zeng for GetFileVersionInfoSize() and GetFileVersionInfo()
#include
#include
#pragma comment( lib , "C:\\Programme\\Microsoft Visual Studio\\VC98\\Lib\\VERSION.LIB" )
//--

代码:
//----Get the file version:
// C:\Programme\Adobe\Reader 8.0\Reader\AcroRd32.exe
long len;
DWORD dwHandle;
len = GetFileVersionInfoSize((LPTSTR)(LPCSTR)sourceDB,&dwHandle);
PTSTR pBuffer = new TCHAR[len];
CString l;
l.Format("%d", len);
AfxMessageBox(l);
memset((void*)pBuffer,0,len);

//get .exe or .DLL resource info, put into pBuffer?
if(GetFileVersionInfo((LPTSTR)(LPCSTR)sourceDB,0,len,(PVOID)pBuffer))
{ //GetFileVersionInfo false.
l.Format("%d", (LPTSTR)pBuffer);
AfxMessageBox(l);
UINT puLen;
//PTSTR lplpBuffer = new TCHAR[len];
VS_FIXEDFILEINFO *lplpBuffer;
if ( VerQueryValue( pBuffer, "\\",(void**)&lplpBuffer, /*(LPVOID*) &lplpBuffer,*/ &puLen ) )
l.Format("%d", lplpBuffer->dwProductVersionLS);
AfxMessageBox(l);
//AfxMessageBox("break");
}

//--



VS_FIXEDFILEINFO 的结构:
typedef struct tagVS_FIXEDFILEINFO
{
DWORD dwSignature; /* e.g. 0xfeef04bd */
DWORD dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
DWORD dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
DWORD dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
DWORD dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
DWORD dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
DWORD dwFileFlagsMask; /* = 0x3F for version "0.42" */
DWORD dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
DWORD dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
DWORD dwFileType; /* e.g. VFT_DRIVER */
DWORD dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
DWORD dwFileDateMS; /* e.g. 0 */
DWORD dwFileDateLS; /* e.g. 0 */
} VS_FIXEDFILEINFO;


参考:
http://www.cpp-tutor.de/mfc/mfc/kap7/lektion8.htm

VC++动态链接库

错误:Nichtaufgeloestes externes Symbol: funA
解决方案:
#pragma comment( lib , "C:\\Programme\\Microsoft Visual Studio\\VC98\\Lib\\VERSION.LIB" )

2007年12月19日星期三

Payback Coupons, gültig bis 31.03.2008

Payback Coupons

create()替代DoModal()打开Dialog

m_pListCt.m_small.Create(IDD_DIALOG_SMALL, this);
m_pListCt.m_small.ShowWindow(SW_SHOW);


//关闭Dialog
m_small.SendMessage(16,0,0);

关闭程序前询问,强行结束进程

void CMainFrame::OnSysCommand(UINT nID,LPARAM lParam)
{
//PostMessage( WM_MY_MESSAGE,0,0);
//SendMessageToDescendants(WM_MY_MESSAGE,0,0,true);
if((nID & 0xFFFFFFF0) ==SC_CLOSE)
{
if(AfxMessageBox("Warning: Wollen Sie die Pozess wicklich abbrechen?",MB_YESNO)!=IDYES)
{

return;
}
else
{
if( !TerminateProcess(GetCurrentProcess(),0) )
AfxMessageBox("Fehlermeldung: Programm kann nicht terminiert werden, bitte versuchen Sie Task-Manager!");

}

//Application->Terminate();
//DestroyWindow();
}
CWnd::OnSysCommand(nID,lParam);
}

获取命令行参数 -s -x...

CWinApp* pApp = AfxGetApp(); //取得CMyWinApp对象指针
pApp-> m_lpCmdLine; //命令行参数,如"-s -q"

2007年12月13日星期四

lstrcat,连结两个LPTSTR 字符串

LPCSTR :指向一个字符串常量的指针(每个字符是占一个字节)
LPCTSTR :指向一个字符串常量的指针(每个字符是占两个字节)
LPTSTR :指向一个字符串的指针(每个字符是占两个字节)

LPTSTR lstrcat(
LPTSTR lpString1,
LPTSTR lpString2
);
Parameters:
lpString1
[in, out] Pointer to a null-terminated string. The buffer must be large enough to contain both strings.
lpString2
[in] Pointer to the null-terminated string to be appended to the string specified in the lpString1 parameter.

Return Value:
If the function succeeds, the return value is a pointer to the buffer.
If the function fails, the return value is NULL and lpString1 may not be null-terminated.

2007年12月12日星期三

高速上险些追尾,魂都吓掉了。。。。只差几厘米

2007年12月11号,阴雨绵绵,一连好几天了。六点钟下了班,一脚油门,从路德维希堡上了高速门,直奔女友学校,打算接上她一起去健身。正值下班高峰,车灯连成一条条长龙,如流光飞逝,随着高低起伏的公路远远望去,疑是银河落九天。。。走神了。大概是上个星期高速上超速三十多被闪的缘故,一路上我开得还算比较慢,小心翼翼,全神贯注。。。保守,再保守。二十多分钟后,高速分道,上了一条三条Fahrbahn的Autobahn,我留在了外道,车流变得拥挤起来,时速还是稳定的保持在90-100左右,不认得路,我一边开一边不时地瞟一下小Navi,也就电光火石的一瞬间,等我的视线重新回到前方路面的时候,前面那辆红车的轮廓在我眼中骤然放大,越来越近,我终于反应过来了,前面在Notbremsen!! 猛踩刹车,身体随着惯性往前猛地一倾,轮胎磨擦路面发出尖啸, 车子还是往前冲,无可阻挡,前面车继续减速中,用力踩,眼睁睁的看着车头往前车屁股上面凑上去。。。凑上去。。。近得都比得上街边的停车车距了,眼看着要顶上车屁股了,我的车好像缓了一缓----其实是前面那辆车松了Bremsen,不再减速了,距离终于拉开,在这一刻,跳到嗓子口的心咚咚的沉了回去,脚松开,这时候时速大概二十多,车挂着五挡的Kupplung一抖一抖的往前爬,回过神来,换二档,还是有点快了,又挂一档,七魂六魄还在游荡,都是下意识的动作。终于停下来了,踩稳刹车,看一下四周,才发现右边道上的车也在慢慢爬,车流又动了,神情恍惚的慢慢往前开,一切都像是虚幻,仿佛不在真实世界里。前面几辆车在打闪要求并道,我也机械跟着打闪,等到前面的红车往右一拐,出现在我眼前的是一个事故现场:两辆车打着双闪,头尾相连。这个时候大家都变得很nett,我一直打着右闪灯,盯着前面两辆破车发愣,右边的车也耐心的停下等我并道,过了好一会我才回过神来,手忙脚乱的并到右边,继续往前开,这时候才发现,自己的手在抖,不知何时,已是一身大汗。

MFC中自由使用自定义消息

消息映射、循环机制是Windows程序运行的基本方式。VC++ MFC 中有许多现成的消息句柄,可当我们需要完成其它的任务,需要自定义消息,就遇到了一些困难。在MFC ClassWizard中不允许添加用户自定义消息,所以我们必须在程序中添加相应代码,以便可以象处理其它消息一样处理自定义消息。通常的做法是采取以下步骤:

  第一步:定义消息。

  推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。

#define WM_MY_MESSAGE (WM_USER+100)

  第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。

LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消息
...
return 0;
}

  第三步:在类头文件的AFX_MSG块中说明消息处理函数:

class CMainFrame:public CMDIFrameWnd
{
...
// 一般消息映射函数
protected:
// {{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}

  第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_TIMER()
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

第五步:发送消息。
//---- use the Frame pointobject
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
pFrame->PostMessage( WM_MY_MESSAGE,0,0);
//--

MFC中消息拦截

Method 1:
BOOL CDbinfoView::PreTranslateMessage(MSG* pMsg)
{
// If edit control is visible in tree view control, when you send a
// WM_KEYDOWN message to the edit control it will dismiss the edit
// control. When the ENTER key was sent to the edit control, the
// parent window of the tree view control is responsible for updating
// the item's label in TVN_ENDLABELEDIT notification code.
if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_LBUTTONDOWN)//pMsg->message == WM_CLOSE)
{
int iID (-1);
switch(pMsg->wParam)
{
case VK_RETURN:

//HWND hWnd=::GetFocus();
//int iID=::GetDlgCtrlID(hWnd);
iID=::GetDlgCtrlID(::GetFocus());

//confirm the message from which Control
if(iID == IDC_EDIT_PATH )
{
//data is being retrieved from DialogForm into FileURL
UpdateData(true);
//Todo:............
}
break;
case VK_TAB:

break;
case VK_LBUTTON:

break;

}

//edit->SendMessage(WM_KEYDOWN, pMsg->wParam, pMsg->lParam);
//return TRUE;

}

// CXxxx can be a CFormView, Cdialog, or CPropertyPage class.
return CWnd::PreTranslateMessage(pMsg);
}


Method 2:

PeekMessage 消息机制
PeekMessage

GetMessage不将控制传回给程序,直到从程序的消息队列中取得消息,但是PeekMessage总是立刻传回,而不论一个消息是否出现。当消息队列中有一个消息时,PeekMessage的传回值为TRUE(非0),并且将按通常方式处理消息。当队列中没有消息时,PeekMessage传回 FALSE(0)。
这使得我们可以改写普通的消息循环。我们可以将如下所示的循环:
while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;


替换为下面的循环:
while (TRUE)

{

if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))

{

if (msg.message == WM_QUIT)

break ;

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

else

{

// 完成某些工作的其它行程序

}

}

return msg.wParam ;


注意,WM_QUIT消息被另外挑出来检查。在普通的消息循环中您不必这么作,因为如果GetMessage接收到一个WM_QUIT消息,它将传回0,但是PeekMessage用它的传回值来指示是否得到一个消息,所以需要对WM_QUIT进行检查。
如果PeekMessage的传回值为TRUE,则消息按通常方式进行处理。如果传回值为FALSE,则在将控制传回给Windows之前,还可以作一点工作(如显示另一个随机矩形)。
(尽管Windows文件上说,您不能用PeekMessage从消息队列中删除WM_PAINT消息,但是这并不是什么大不了的问题。毕竟, GetMessage并不从消息队列中删除WM_PAINT消息。从队列中删除WM_PAINT消息的唯一方法是令窗口显示区域的失效区域变得有效,这可以用ValidateRect和ValidateRgn或者BeginPaint和EndPaint对来完成。如果您在使用PeekMessage从队列中取出WM_PAINT消息后,同平常一样处理它,那么就不会有问题了。所不能作的是使用如下所示的程序代码来清除消息队列中的所有消息:
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) ;


这行叙述从消息队列中删除WM_PAINT之外的所有消息。如果队列中有一个WM_PAINT消息,程序就会永远地陷在while循环中。)

通过OnSysCommand关闭程序控制

在MainFrame利用WINDOWS的消息循环机制,拦截关闭窗口消息:
1:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
//手动添加:
ON_MESSAGE(WM_SYSCOMMAND,OnSysCommand)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

2:
void CMainFrame::OnSysCommand(UINT nID,LPARAM lParam)
{
if((nID & 0xFFFFFFF0) ==SC_CLOSE)
{
if(AfxMessageBox("Warning: Wollen Sie die Pozess wicklich abbrechen?",MB_OKCANCEL)!=IDOK)
return;
//如果关闭程序 do something:..........
}
CWnd::OnSysCommand(nID,lParam);
}


3.在CDialog中:

void CDBinfoSmall::OnSysCommand(UINT nID, LPARAM lParam)
{
//AfxMessageBox("mouse call");
if((nID & 0xFFFFFFF0) == SC_CLOSE)
{

if(AfxMessageBox("Warning: Wollen Sie die Pozess wicklich abbrechen?",MB_YESNO) == IDNO)
{

//AfxMessageBox( GetCommandLine() );
return;

}
else
{
//---- use the View pointobject, close the m_DaoDatabase;
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;

// Get the active MDI child window.
CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();

// or CMDIChildWnd *pChild = pFrame->MDIGetActive();

// Get the active view attached to the active MDI child window.
CDbinfoView *pView = (CDbinfoView *) pChild->GetActiveView();

//close the source db m_DaoDatabase by using pView
if( pView->m_DaoDatabase.IsOpen())
{
pView->m_DaoDatabase.Close();
//
//AfxMessageBox("m_DaoDatabase.Close();");

}
if (plc.existFile(plc.InstallDir + "\\Database\\apollo.ldb"))
DeleteFile(plc.InstallDir + "\\Database\\apollo.ldb");
//close the target db in cdbinfolistct,
//pView->m_pListCt.DB_Close(); //runtime error!!
//----
if( !TerminateProcess(GetCurrentProcess(),0) )
AfxMessageBox("Fehlermeldung: Programm kann nicht terminiert werden, bitte versuchen Sie Task-Manager!");

}

}

/////////////////////////////////////////////////
//
// * Making other messages be answered, e.SC_MOVE
//
/////////////////////////////////////////////////
CDialog::OnSysCommand(nID,lParam);

}


4.OnSysCommand() 与 OnLButtonDown()在CDialog中响应区别:

OnSysCommand 响应了对对话框标题栏的鼠标点击
OnLButtonDown 响应了对对话框框体的鼠标点击(不包括标题栏)

RGB color codes

http://www.pitt.edu/~nisg/cis/web/cgi/rgb.html

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之间。