mfc​使用CRect编译提示mfc未定义标识符符 同一工程的其他cpp文件中却能通过编译……

vs2008 MFC问题编译无法通过_百度知道
vs2008 MFC问题编译无法通过
我是用Win32控制台写的,最简单的MFC程序Hello.hclass CMyApp:public CWinApp{public: virtual BOOL InitInstance();};class CMainWindow:public CFrameWnd{public: CMainWindow();protected: afx_msg void OnPaint(); DECLARE_MESSAGE_MAP()};Hello.cpp#include&afxwin.h&#include&Hello.h&CMyApp myABOOL CMyApp::InitInstance(){ m_pMainWnd = new CMainW m_pMainWnd-&ShowWindow(m_nCmdShow); m_pMainWnd-&UpdateWindow(); return TRUE;}BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd) ON_WM_PAINT()END_MESSAGE_MAP()CMainWindow::CMainWindow(){ Create(NULL,_T(&The Hello Application&));}void CMainWindow::OnPaint(){ CPaintDC dc(this); CR GetClientRect(&rect); dc.DrawText(_T(&Hello,MFC&),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);}编译无法通过,提示1&msvcrtd.lib(crtexe.obj) : error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用1&D:\Program Files\backup\Visual Studio 2008\Projects\helloMFC\Debug\helloMFC.exe : fatal error LNK1120: 1 个无法解析的外部命令求指点。。。
提问者采纳
你是在控制台里面建立的,自然会有问题。右键该工程--属性---常规 --项目默认值--MFC的使用----在共享DLL中使用MFC,一定要设这一步。更好的方法是你建立一个MFC程序,把里面的.H和 CPP文件统统删了,再自己建立CPP等。
这个错误是在改为共享之后发生的。。。建立一个MFC程序同时还有一个文件啊!那个文件里的东西怎么办?
属性--配置属性--链接器--系统-子系统---窗口(/SUBSYSTEM:WINDOWS).主要是入口函数的问题
提问者评价
虽然你的回答没有解决问题,但是已经非常靠谱了。我解决了,建项目的时候建错了,应该是win32项目···
其他类似问题
为您推荐:
vs2008的相关知识
其他1条回答
原来安装过VC6吧 建议还是重做系统 在装2008 比较彻底和干净
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁MFC基本应用_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
文档贡献者
评价文档:
MFC基本应用
m​f​c
大小:400.50KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢使用MFC(单文档)编的串口通信程序,编译时没有错误,最后执行时,总是提示“建立空文档失败”_百度知道
使用MFC(单文档)编的串口通信程序,编译时没有错误,最后执行时,总是提示“建立空文档失败”
int CSDICommView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here m_MSComm.Create(NULL,0,CRect(0,0,0,0),this,IDC_MSCOMM1);//创建控件 m_MSComm.SetCommPort(2);//选择COM2 m_MSComm.SetInBufferSize(1024);//接收缓冲区 m_MSComm.SetOutBufferSize(1024);//发送缓冲区 m_MSComm.SetInputLen(0);//设置当前接收区数据长度为0,表示全部读取 m_MSComm.SetInputMode(1);//以二进制方式读取数据 m_MSComm.SetRThreshold(1);//接收缓冲区有5个或5个以上字符时,将引发接收数据的OnComm事件 m_MSComm.SetSettings(&9600,n,8,1&);//波特率:9600,校验位:无,数据位:8位,停止位:1位// if(!m_MSComm.GetPortOpen())//如果串口没打开,则打开串口//
m_MSComm.SetPortOpen(TRUE);// else//
AfxMessageBox(&打开串口失败!&);// m_MSComm.GetInput();//先预读缓冲区,以清除残留数据 return 0;}我一句句试了下,问题出在问题出在if语句和m_MSComm.GetInput(),这是为什么呢?我该怎样修改程序?
编译时会有警告:compiler option 'Generate Browser Info' inconsistent wit current command-line option will override that defined in the precompiled header
提问者采纳
//m_MSComm.GetInput();//先预读缓冲区,以清除残留数据应该是有返回值的吧,有返回值的话,return 0这句就执行不到了,int CSDICommView::OnCreate(LPCREATESTRUCT lpCreateStruct) 的建议就“建立空文档失败”//m_MSComm.GetInput();//先预读缓冲区,以清除残留数据
这句可以放在真正读数据之前。
前面的if语句中的“m_MSComm.SetPortOpen(TRUE);”有时也会出错!我要在建立文档的时候就打开串口,应该放在其它什么位置好呢?
“m_MSComm.SetPortOpen(TRUE);”出错那就退出呗,因为com口有可能被其它程序占用了啊!比如说你自己本身程序打开了,但未关闭串口,你再次使用肯定不行了。
其他类似问题
为您推荐:
其他3条回答
你把菜单栏里的ON_FILE_NEW给删了吧?建立空文档失败应该是那个原因
网上找个串口类用吧,串口控件太难用了
清理完项目 ------------ 重新编译一下
串口通信的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁1."属性页的添加:创建对话框的类,该类要从CpropertyPage继承; 然后在要添加该对话框为属性页的类(头文件)里创建CpropertySheet类的一个对象m_tabsheet和新创建的对话框类的对象m_skatch; 最后,在.cpp文件里的OnInitDialog()之类的函数里实现如下代码: { m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE, 0);
//使选项卡的按钮在下面
if(m_tabsheet.m_hWnd)
m_tabsheet.ShowWindow(SW_MAXIMIZE);
//显示选项卡
//加入标签,标签名由各个子对话框的标题栏决定
m_tabsheet.AddPage(&m_skatch);
//用Create来创建一个属性页
m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE, WS_EX_CONTROLPARENT);
m_tabsheet.GetWindowRect(&rect);
int width = rect.right - rect.
int height = rect.bottom - rect.
//调整属性页的大小和位置
m_tabsheet.SetWindowPos(NULL, 225, 225, width-82, height,SWP_NOACTIVATE);
//属性页的添加完成。如果要添加多个属性页,则只需要增加多个对象,如下:
m_tabsheet.AddPage(&m_skatch1);
m_tabsheet.AddPage(&m_skatch2);
2."List Control中标题栏(Column)的添加:创建一个List Control,其ID为IDC_LIST,在其Styles属性项下的View项里选择Report、Align项里选择Top、Sort项里选择None.然后在该List所在对话框的类(头文件)里创建ClistCtrl的一个对象m_list
然后在.cpp文件的OnInitDialog()之类的函数里实现如下代码:CString strname[3];
strname[0]="Screen Name";
strname[1]="Form ID";
strname[2]="Category Path";
for(int i=0;i&3;i++)
m_List.InsertColumn(i,strname[i],LVCFMT_LEFT,130);
在这之前也要将List Control的ID与ClistCtrl的对象m_list在DoDataExchange(CDataExchange* pDX)函数里绑定,如下:DDX_Control(pDX, IDC_LIST, m_List);
3."ToolBar和StatusBar中控件的添加:方法⑴.只能在ToolBar里创建控件:
首先,在ToolBar中创建一个Button,其ID为ID_TOOL_COMBO(我们要将创建的控件放在该Button的位置上).
其次,新创建一个类CMainToolBar,要从CToolBar继承(创建过程大概如下:选择工程/增加到工程/新的类;也可以选择工程的根,然后点击右键,选择新的类;或者CTL+W,选择增加类/新的类 ---
然后在class type里选择Generic Class,在Name栏里输入新类的名字,Base class里输入CToolBar),创建成功后在该类里创建要增加的控件的对象,如:CComboBox& m_wndMyC CStatic& m_wndCategory, m_wndCategoryPCButton& m_wndOpenBCedit& m_wndE然后在构造函数里初始化如:m_wndMyCombo.m_hWnd = NULL;m_wndCategory.m_hWnd = NULL;m_wndCategoryPath.m_hWnd = NULL;m_wndOpenButton.m_hWnd = NULL;m_wndEdit.m_hWnd = NULL;接着在CMainframe的头文件里创建CMainToolBar的一个对象m_wndToolBar,最后在.cpp文件的OnCreate函数的最后实现如下:int index = 0; CR 
// 可定义在头文件当中 // 
//找到指定的工具项
while(m_wndToolBar.GetItemID(index)!=ID_TOOL_COMBO)
//设置指定工具项的宽度并获取新的区域 120是宽度
m_wndToolBar.SetButtonInfo(index, ID_TOOL_COMBO, TBBS_SEPARATOR, 120);
m_wndToolBar.GetItemRect(index, &rect);
//设置位置
rect.top+=1;
rect.bottom += 200;
// 创建并显示控件
if(!m_wndToolBar.m_wndMyCombo.Create(WS_CHILD|WS_VISIBLE| CBS_AUTOHSCROLL|CBS_DROPDOWNLIST | CBS_HASSTRINGS , rect, &m_wndToolBar,ID_TOOL_COMBO))
TRACE0("Failed to create combo-box\n");
return FALSE;
m_wndToolBar.m_wndMyCombo.ShowWindow(SW_SHOW);
//填充内容"
m_wndToolBar.m_wndMyCombo.AddString("25%");
m_wndToolBar.m_wndMyCombo.AddString("50%");
m_wndToolBar.m_wndMyCombo.AddString("75%");
//选择默认项
m_wndToolBar.m_wndMyCombo.SetCurSel(0);
//获取到内容并MSGBOX显示出来
CString strC m_wndToolBar.m_wndMyCombo.GetWindowText(strContent);
index = 0;
其他控件都类似创建(只需要注意一下各自的Create函数的参数即可)。
方法⑵.这种方法创建不太容易控制:直接在CMainframe的头文件中创建要增加的控件的对象,如CButton"的对象m_wndAboutButton,然后创建CToolBar或者CstatusBar的对象,如:CstatusBar的对象_wndStatusBar;再增加几个函数如下:Protected:
virtual void RecalcLayout(BOOL bNotify = TRUE);
"afx_msg void CMainFrame::OnViewStatusBar();接着在.cpp文件中将StatusBar的ID和OnViewStatusBar 函数绑定在一起,如下所示:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)   
// {{AFX_MSG_MAP(CMainFrame)   
ON_COMMAND(ID_VIEW_STATUS_BAR, OnViewStatusBar)   
ON_WM_CREATE()   
// }}AFX_MSG_MAP END_MESSAGE_MAP()
然后Create函数的最后(返回值之前)实现如下代码:
VERIFY(m_wndAboutButton.Create(_T("MyAbout"),  
WS_VISIBLE,rc,this,ID_APP_ABOUT));
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
再在RecalcLayout函数里实现:
if (m_wndStatusBar.m_hWnd)
m_wndStatusBar.GetWindowRect(&rc);
ScreenToClient(&rc);
rc.right -= 50;
m_wndStatusBar.SetWindowPos(NULL,rc.left,rc.top,rc.Width(),rc.Height(), SWP_NOZORDER);
rc.left = rc.
rc.right += 50;
m_wndAboutButton.SetWindowPos(NULL,rc.left,rc.top,rc.Width(),rc.Height(), SWP_NOZORDER);
}最后在OnViewStatusBar()里实现:
BOOL bShow = m_wndStatusBar.GetStyle() & WS_VISIBLE;
m_wndAboutButton.SetWindowPos(NULL, 0, 0, 0, 0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE| (bShow ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
ToolBar中的创建与此相同,只需更改一下句柄即可。
4."通过Control创建的控件,对其属性的动态控制:在对话框类的头文件里创建所要改变属性的控件的对象,如要改变一个Button(其ID为IDC_MyButton)的属性,则需创建Cbutton的对象m_button。然后在.cpp中的DoDataExchange函数里将Button的ID和创建的对象绑定在一起:
//{{AFX_DATA_MAP(CPrintDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
DDX_Control(pDX, IDC_MyButton, m_button);
//}}AFX_DATA_MAP 然后可以在该函数的最后进行初始化:m_button.EnableWindow(FALSE);到这里已经实现了改变属性。如果要动态改变其属性,可如下实现(通过两个Button的点击改变起属性):// RadioAll Button的点击响应函数void CPrintDlg::OnRadioAll()
{ // TODO: Add your control notification handler code here
m_button.EnableWindow(TRUE);
// RadioSelect Button的点击响应
void CPrintDlg::OnRadioSelect()
{ // TODO: Add your control notification handler code here
m_button.EnableWindow(FALSE);
也可以通过一个Check Button的点击来改变,在其点击响应函数里实现:m_button.EnableWindow(!m_button.IsWindowEnabled());其余控件属性的改变都如此。
5."窗口的分割与停靠:                        一、新建一个类CMySplitter,基类为CSplitterWnd二、重载该类的OnMouseMove函数:void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
// 限制切分条的运动范围。
if(point.x&228||point.x&600)
CWnd::OnMouseMove(nFlags, point);
CSplitterWnd::OnMouseMove(nFlags, point);
三、 然后就可以跟一般的窗口分割那样去做了,if(point.x&228||point.x&600)这里的范围可以随你去设置了 ^_^,够简单吧。四、切分窗口在MaiFram.h建立切分条对象:protected:
CMySplitter m_wndS
//切分窗口对象
//在MaiFram.cpp中实现窗口切分:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,CCreateContext* pContext)
// 创建拆分器窗口
if (!m_wndSplitter.CreateStatic(this, 1, 2))
return FALSE;
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView),CSize(228,100),pContext) ||!m_wndSplitter.CreateView(0,1, RUNTIME_CLASS(CDataEditView), CSize(100, 100), pContext))
{ m_wndSplitter.DestroyWindow();
return FALSE;
return TRUE;
6.一些重要的问题
①怎样在程序开始的时候让它最大化?②vc++做出来的exe文件在窗体的右上方是没有最大化和最小化按钮的,怎样实现这一功能? ③如何在显示窗口时,使最大化按钮变灰?
①在App类里的C…App::InitInstance()中把m_pMainWnd-&ShowWindow(SW_SHOW)改成m_pMainWnd-&ShowWindow(SW_MAXIMIZE);②在CreateWidnow时用WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX 风格.③ 第一种方法:BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs // disable the
maxmini box cs.style &= ~WS_MAXIMIZEBOX;
return TRUE;
第二种方法:CMenu *pMenu=AfxGetApp()-&m_pMainWnd-&GetSystemMenu(FALSE);
int x=pMenu-&GetMenuItemCount( );
UINT pID=pMenu-&GetMenuItemID(x-1);
pMenu-&EnableMenuItem(pID, MF_DISABLED);
第三种方法:ModifyStyle(WS_MAXIMIZEBOX, 0); 这个函数也可以是最大化按钮失效!并且可以在程序中动态的改变窗口的风格
7. 更改属性页标题void CProSheet::SetPageTitle(int nPage, int nImage, CString strTitle)
// item.mask = TCIF_TEXT|TCIF_IMAGE;
//设置图标+文字
item.mask = TCIF_IMAGE;
//只设置图标
item.iImage = nI
// item.pszText = strTitle.GetBuffer(0);
//设置文字 GetTabControl ()-&SetItem (nPage, &item);
//要设置文字时就将上面2行有注释符的代码前的注释符去掉
8. 创建动态菜单void CMainFrame::OnSelectState(NMTOOLBAR* pnmtb, LRESULT *plr)
if(!menu.CreateMenu())
menu.AppendMenu(MF_STRING,0, 开始 );
menu.AppendMenu(MF_STRING,0, 结束 );
m_wndToolBar.SendMessage(TB_GETRECT, pnmtb-&iItem, (LPARAM)&rc);
m_wndToolBar.ClientToScreen(&rc);
menu.TrackMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL, rc.left, rc.bottom, this, &rc);
// menu.DestroyMenu();
menu.detach();
9.关于打印1.要打印哪个视就((CMainFrame*)AfxGetMainWnd())-&m_wndSplitter.SetActivePane(...) //要打印的那个视对应的Pane
2.有一个单文档工程,文档窗口被切分:左视图由CTreeView 的派生类管理,右视图由CListView 的派生类CMyListView(其为风格为LVS_REPORT)管理,我想为右视图添加打印和打印预览,我在MyListView.cpp中添加了ON_COMMAND(ID_FILE_PRINT,CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CListView::OnFilePrintPreview)
BOOL CMyListView::OnPreparePrinting(CPrintInfo* pInfo)
// TODO: call DoPreparePrinting to invoke the Print dialog box //
return CListView::OnPreparePrinting(pInfo);
pInfo-&SetMaxPage(2);
BOOL bret=DoPreparePrinting(pInfo);
pInfo-&m_nNumPreviewPages=2;
3. 下面是从MSDN中摘出来的一段,是用来改变消息路由的。用了这段代码之后,CView中的消息(菜单,控件,子窗口)将先被CMyShape类来处理。不知道你要的是不是这样的效果。
// This example illustrates extending the framework's standard command
// route from the view to objects managed by the view. This example
// is from an object-oriented drawing application, similar to the
// DRAWCLI sample application, which draws and edits shapes .
BOOL CMyView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
// Extend the framework's command route from the view to
// the application-specific CMyShape that is currently selected
// in the view. m_pActiveShape is NULL if no shape object
// is currently selected in the view.
if ((m_pActiveShape != NULL) && m_pActiveShape-&OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
// If the object(s) in the extended command route don't handle
// the command, then let the base class OnCmdMsg handle it.
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
// The command handler for ID_SHAPE_COLOR (menu command to change
// the color of the currently selected shape) was added to
// the message map of CMyShape (note, not CMyView) using ClassWizard.
// The menu item will be automatically enabled or disabled, depending
// on whether a CMyShape is currently selected in the view, that is,
// depending on whether CMyView::m_pActiveView is NULL. It is not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape, CCmdTarget)
//{{AFX_MSG_MAP(CMyShape)
ON_COMMAND(ID_SHAPE_COLOR, OnShapeColor)
//}}AFX_MSG_MAP END_MESSAGE_MAP()
如果你只是想调用OnFilePrint( )函数,可以试一试下面的代码,就和调用其它类中的函数一样。CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()-&m_pMainW
// 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.
CMyView *pView = (CMyView *) pChild-&GetActiveView();
pView-&OnFilePrint( );
4.void CMyReportView::OnFileOpen() { char Filter[] = Crystal Report files(*.rpt)|*.rpt|All files(*.*)|*.*|| ; CR CFileDialog OpenDlg(TRUE,0,0,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,(LPCTSTR)Filter,NULL); if(OpenDlg.DoModal()!=IDOK) ///显示文件对话框 CString m_fName=OpenDlg.GetPathName(); ///取得文件名 if(m_CrystalReport) m_CrystalReport.DestroyWindow(); GetClientRect(rect); ///////////////////创建控件/////////////// if (!m_CrystalReport.Create(AfxRegisterWndClass(0, AfxGetApp()-&LoadStandardCursor(IDC_ARROW)),WS_CHILD|WS_VISIBLE,rect,this,IDC_CRYSTALREPORT1))
AfxMessageBox( 控件创建失败! );
m_CrystalReport.SetWindowParentHandle((long)(this-&m_hWnd));
///设置父窗口
m_CrystalReport.SetWindowBorderStyle(0);
///设置为没有边框
m_CrystalReport.SetWindowLeft(0);
m_CrystalReport.SetWindowTop(0);
///顶部空间
m_CrystalReport.SetWindowControls(FALSE);
///不显示工具条
m_CrystalReport.SetReportFileName(m_fName);
///设置报表文件
m_CrystalReport.SetWindowWidth(rect.Width());
///设置窗口宽度
m_CrystalReport.SetWindowHeight(rect.Height());
///设置窗口高度
m_CrystalReport.SetFormulas(0, Company=\ VC知识库\ );
///将报表中的Company变量的值设置为VC知识库
m_CrystalReport.SetDestination(0);
///设置输出对象是屏幕
m_CrystalReport.PrintReport();
///显示报表
void CMyReportView::OnFilePrint()
if(m_CrystalReport && m_CrystalReport.GetReportFileName() != )
m_CrystalReport.SetDestination(1);
///设置输出对象是打印机
m_CrystalReport.PrintReport();
10. Scroll创建一个基于CScrollview的SDI Project(在第6步中选CScrollview)若你已创建了,这步可以省略。然后:改为如void CTestView::OnInitialUpdate()
CScrollView::OnInitialUpdate();
CSize sizeT
// TODO: calculate the total size of this view sizeTotal.cx = 1024;
//改这两个
sizeTotal.cy = 768;
SetScrollSizes(MM_TEXT, sizeTotal);
11. 修改主窗口风格AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名、窗口是叠加型的、可改变窗口大小等。要修改窗口的缺省风格,需要重载CWnd::PreCreateWindow(CREATESTRUCT& cs)函数,并在其中修改CREATESTRUCT型参数cs。CWnd::PreCreateWindow 函数先于窗口创建函数执行。如果该函数被重载,则窗口创建函数将使用CWnd::PreCreateWindow 函数返回的CREATESTRUCT cs参数所定义的窗口风格来创建窗口;否则使用预定义的窗口风格。CREATESTRUCT结构定义了创建函数创建窗口所用的初始参数,其定义如下:typedef struct tagCREATESTRUCT
LPVOID lpCreateP
// 创建窗口的基本参数
// 拥有将创建的窗口的模块实例句柄
// 新窗口的菜单句柄
HWND hwndP
// 新窗口的父窗口句柄
int // 新窗口的高度
int // 新窗口的宽度
int // 新窗口的左上角Y坐标
int // 新窗口的左上角X坐标
LONG // 新窗口的风格
LPCSTR lpszN // 新窗口的名称
LPCSTR lpszC // 新窗口的窗口类名
DWORD dwExS // 新窗口的扩展参数
} CREATESTRUCT;
CREATESTRUCT结构的style域定义了窗口的风格。比如,缺省的MDI主窗口的风格中就包括FWS_ADDTOTITLE(在标题条中显示当前的工作文档名)、FWS_PREFIXTITLE(把文档名放在程序标题的前面)、WS_THICKFRAME(窗口具有可缩放的边框)等风格。由于多种风格参数由逻辑或( | )组合在一起的,因此添加某种风格,就只需用 | 把对应的参数加到CREATESTRUCT结构的style域中;删除已有的风格,则需用 & 连接CREATESTRUCT结构的style域与该风格的逻辑非值。CREATESTRUCT结构的x、y、cx、cy域分别定义了窗口的初始位置和大小,因此,在CWnd::PreCreateWindow 函数中给它们赋值,将能定义窗口的初始显示位置和大小。下例中的代码将主框窗口的大小将固定为1/4屏幕,标题条中仅显示窗口名,不显示文档名。BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
// TODO: Modify the Window class or styles here by modifying // the
CREATESTRUCT cs
// 修改主窗风格
cs.style &= ~FWS_ADDTOTITLE;
//去除标题条中的文档名
cs.style &= ~WS_THICKFRAME;
//去除可改变大小的边框
cs.style |= WS_DLGFRAME; //增加不能改变大小的边框
// 确定主窗的大小和初始位置
int cxScreen = ::GetSystemMetrics(SM_CXSCREEN);//获得屏幕宽
int cyScreen = ::GetSystemMetrics(SM_CYSCREEN); //获得屏幕高
cs.x = 0; // 主窗位于左上角
cs.y = 0; cs.cx = cxScreen/2; // 主窗宽为1/2屏幕宽
cs.cy = cxScreen/2; // 主窗高为1/2屏幕高
return CMDIFrameWnd::PreCreateWindow(cs);
12. 控制滚动条BOOL CDiagramShowView::PreTranslateMessage(MSG* pMsg)
CFileTreeDoc* pDoc = (CFileTreeDoc*)GetDocument();
CPoint point = GetScrollPosition();
if(pMsg-&message == WM_KEYDOWN)
switch(pMsg-&wParam)
case VK_LEFT:
if( point.x & 10)
EndPoint.x = EndPoint.x - 10;
EndPoint.y = EndPoint.y;
EndPoint.x = 0;
EndPoint.y = EndPoint.y;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
case VK_RIGHT:
if( point.x & pDoc-&intDiagramColumnCount * pDoc-&intColumnWidth - 10 )
EndPoint.x = EndPoint.x + 10;
EndPoint.y = EndPoint.y;
EndPoint.y = pDoc-&intDiagramColumnCount * pDoc-&intColumnW
EndPoint.x = EndPoint.x;
ScrollToPosition(EndPoint); InvalidateRect(NULL,TRUE);
case VK_UP:
if( point.y & 10)
{ EndPoint.y = EndPoint.y - 10;
EndPoint.x = EndPoint.x;
EndPoint.y = 0;
EndPoint.x = EndPoint.x;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
case VK_DOWN:
if( point.y & pDoc-&intDiagramRowCount * pDoc-&intRowHeight - 10 )
EndPoint.y = EndPoint.y + 10;
EndPoint.x = EndPoint.x;
EndPoint.y = pDoc-&intDiagramRowCount * pDoc-&intRowH
EndPoint.x = EndPoint.x;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
return FALSE;
// 通过正负号判断是向上还是向下滚动 if(zDelta==120) 向上滚动 if(zDelta==-120) 向下滚动
BOOL CDiagramShowView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
CFileTreeDoc* pDoc = (CFileTreeDoc*)GetDocument();
CPoint point = GetScrollPosition();
if(zDelta==120)
if( point.y &= 20 )
EndPoint.x = point.x;
EndPoint.y = point.y;
EndPoint.x = EndPoint.x;
EndPoint.y = EndPoint.y - 20;
EndPoint.x = EndPoint.x;
EndPoint.y = 0;
if(zDelta==-120)
if( point.y &= pDoc-&intDiagramRowCount * pDoc-&intRowHeight - 20 )
EndPoint.x = point.x;
EndPoint.y = point.y;
EndPoint.x = EndPoint.x;
EndPoint.y = EndPoint.y + 20;
EndPoint.x = EndPoint.x;
EndPoint.y = EndPoint.y;
ScrollToPosition(EndPoint);
InvalidateRect(NULL,TRUE);
return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
13. 属性页处理通知消息CPropertyPageImpl有一个消息映射处理WM_NOTIFY。如果通知代码是PSN_*的值,OnNotify()就会调用相应的通知处理函数。这使用了编译阶段虚函数机制,从而使得派生类可以很容易的重载这些处理函数。由于WTL 3和WTL 7设计的改变,从而存在两套不同的通知处理机制。在WTL 3中通知处理函数返回的值与PSN_*消息的返回值不同,例如,WTL 3是这样处理PSN_WIZFINISH的:case PSN_WIZFINISH:
lResult = !pT-&OnWizardFinish();
OnWizardFinish()期望返回TRUE结束向导,FALSE阻止关闭向导。这个方法很简陋,但是IE5的通用控件对PSN_WIZFINISH处理的返回值添加了新解释,他返回需要获得焦点的窗口的句柄。WTL 3的程序将不能使用这个特性,因为它对所有非0的返回值都做相同的处理。在WTL 7中,OnNotify() 没有改变 PSN_* 消息的返回值,处理函数返回任何文档中规定的合法数值和正确的行为。当然,为了向前兼容,WTL 3 仍然使用当前默认的工作方式,要使用WTL 7的消息处理方式,你必须在中including atldlgs.h一行之前添加一行定义:
#define _WTL_NEW_PAGE_NOTIFY_HANDLERS
编写新的代码没有理由不使用WTL 7的消息处理函数,所以这里就不介绍WTL 3的消息处理方式。CPropertyPageImpl 为所有消息提供了默认的通知消息处理函数,你可以重载与你的程序有关的消息处理函数完成特殊的操作。默认的消息处理函数和相应的行为如下:int OnSetActive() - 允许页面成为激活状态BOOL OnKillActive() - 允许页面成为非激活状态int OnApply() - 返回 PSNRET_NOERROR 表示应用操作成功完成void OnReset() - 无相应的动作BOOL OnQueryCancel() - 允许取消操作int OnWizardBack() - 返回到前一个页面int OnWizardNext() - 进行到下一个页面INT_PTR OnWizardFinish() - 允许向导结束void OnHelp() - 无相应的动作BOOL OnGetObject(LPNMOBJECTNOTIFY lpObjectNotify) - 无相应的动作int OnTranslateAccelerator(LPMSG lpMsg) - 返回 PSNRET_NOERROR 表示消息没有被处理HWND OnQueryInitialFocus(HWND hWndFocus) - 返回 NULL 表示将按Tab Order顺序的第一个控件设为焦点状态
14.使工具条上的按钮点击一次为按下,再点击才弹起bCheck=m_RtfEditToolBar.GetToolBarCtrl().IsButtonChecked(ID_TB_BOLD); m_RtfEditToolBar.GetToolBarCtrl().CheckButton(ID_TB_BOLD, !bCheck);
15. VC中基于 Windows 的精确定时在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要精确定时操作。  众所周知,Windows 是基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的。这样就带来了一些问题,如一旦计算机的CPU被某个进程占用,或系统资源紧张时,发送到消息队列 中的消息就暂时被挂起,得不到实时处理。因此,不能简单地通过Windows消息引发一个对定时要求 严格的事件。另外,由于在Windows中已经封装了计算机底层硬件的访问,所以,要想通过直接利用访问硬件来完成精确定时,也比较困难。所以在实际应用时,应针对具体定时精度的要求,采取相适 应的定时方法。VC中提供了很多关于时间操作的函数,利用它们控制程序能够精确地完成定时和计时操作。本文详细介绍了 VC中基于Windows的精确定时的七种方式.  方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时 间隔,如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法非常简单,可以实现一定的定时功能,但其定时功能如同Sleep()函数的延时功能一样,精度非常低,最小 计时精度仅为30ms,CPU占用低,且定时器消息在多任务操作系统中的优先级很低,不能得到及时响应,往往不能满足实时控制环境下的应用。只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。如示例工程中的Timer1。  方式二:VC中使用sleep()函数实现延时,它的单位是ms,如延时2秒,用sleep(2000)。精度非常低,最小计时精度仅为30ms,用sleep函数的不利处在于延时期间不能处理其他的消息,如果时间太长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer2。  方式三:利用COleDateTime类和COleDateTimeSpan类结合WINDOWS的消息处理过程来实现秒级延时。如示例工程中的Timer3和Timer3_1。以下是实现2秒的延时代码:COleDateTime start_time = COleDateTime::GetCurrentTime();
COleDateTimeSpan end_time= COleDateTime::GetCurrentTime()-&start_
while(end_time.GetTotalSeconds()& 2) //实现延时2秒
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg); DispatchMessage(&msg);
//以上四行是实现在延时或定时期间能处理其他的消息,
//虽然这样可以降低CPU的占有率,
//但降低了延时或定时精度,实际应用中可以去掉。
end_time = COleDateTime::GetCurrentTime()-&start_
}//这样在延时的时候我们也能够处理其他的消息。   
  方式四:在精度要求较高的情况下,VC中可以利用GetTickCount()函数,该函数的返回值是 DWORD型,表示以ms为单位的计算机启动后经历的时间间隔。精度比WM_TIMER消息映射高,在较 短的定时中其计时误差为15ms,在较长的定时中其计时误差较低,如果定时时间太长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer4和Timer4_1。下列代码可以实现50ms的精确定时:DWORD dwStart = GetTickCount();
DWORD dwEnd = dwS
dwEnd = GetTickCount()-&dwS
while(dwEnd &50);
//为使GetTickCount()函数在延时或定时期间能处理其他的消息,可以把代码改为:
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwS
MSG GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
dwEnd = GetTickCount()-dwS
while(dwEnd &50);
虽然这样可以降低CPU的占有率,并在延时或定时期间也能处理其他的消息,但降低了延时或定时精度。  方式五:与GetTickCount()函数类似的多媒体定时器函数DWORD timeGetTime(void),该函数定时精 度为ms级,返回从Windows启动开始经过的毫秒数。微软公司在其多媒体Windows中提供了精确定时器的底层API持,利用多媒体定时器可以很精确地读出系统的当前时间,并且能在非常精确的时间间隔内完成一 个事件、函数或过程的调用。不同之处在于调用DWORD timeGetTime(void) 函数之前必须将 Winmm.lib 和 Mmsystem.h 添加到工程中,否则在编译时提示DWORD timeGetTime(void)函数未定义。由于使用该 函数是通过查询的方式进行定时控制的,所以,应该建立定时循环来进行定时事件的控制。如示例工程中的Timer5和Timer5_1。  方式六:使用多媒体定时器timeSetEvent()函数,该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。如示例工程中的Timer6和Timer6_1。函数的原型如下:MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )
  该函数设置一个定时回调事件,此事件可以是一个一次性事件或周期性事件。事件一旦被激活,便调用指定的回调函数, 成功后返回事件的标识符代码,否则返回NULL。函数的参数说明如下:uDelay:以毫秒指定事件的周期。Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。LpTimeProc:指向一个回调函数。DwUser:存放用户提供的回调数据。FuEvent:指定定时器事件类型:TIME_ONESHOT:uDelay毫秒后只产生一次事件TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。     具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在LpTimeProc回调函数 中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是,任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后, 应及时调用timeKillEvent()将之释放。  方式七:对于精确度要求更高的定时操作,则应该使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows 95及其后续版本使用的精确时间函数,并要求计算机从硬件上支持精确定时器。如示例工程中的Timer7、Timer7_1、Timer7_2、Timer7_3。QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下:BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);
//数据类型ARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typedef union _LARGE_INTEGER
DWORD LowP// 4字节整型数
LONG HighP// 4字节整型数
LONGLONG QuadP// 8字节整型数
}LARGE_INTEGER ;
  在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率,然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。下列代码实现1ms的精确定时:LARGE_INTEGER
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfT
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadP// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadP// 获得初始值
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadP//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfF// 获得对应的时间值,单位为秒
}while(dfTim&0.001);
  其定时误差不超过1微秒,精度与CPU等机器配置有关。下面的程序用来测试函数Sleep(100)的精确持续时间:LARGE_INTEGER
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfT
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadP// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadP// 获得初始值
Sleep(100);
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadP//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfF// 获得对应的时间值,单位为秒  
  由于Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。下列代码实现1微秒的精确定时:LARGE_INTEGER
LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfT
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadP// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadP// 获得初始值
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadP//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfF// 获得对应的时间值,单位为秒
}while(dfTim&0.000001);
其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关。
16. 为对话框中的控件增加提示的简单方法我学VC从VC知识库中得到不少好处,相来都是一些热心朋友们的帮助,在此表示感谢!本工程可分五步:1、建一个基于对话框的程序TipTest,在CTipTestDlg中增加成员变量:CToolTipCtrl m_tip[2],CWnd *m_pSub[2];2、在CTipTestDlg::OnInitDialog()函数中增加如下代码: pSub[0] = GetDlgItem(IDC_RADIO1); //得到单选按钮的指针
pSub[1] = GetDlgItem(IDC_BUTTON1);
m_tip[0].Create(pSub[0],TTS_ALWAYSTIP); //创建
CToolTipCtrl m_tip[0].AddTool(pSub[0]); //将CToolTipCtrl与相应的控件对应起来
m_tip[1].Create(pSub[1],TTS_ALWAYSTIP);
m_tip[1].AddTool(pSub[1]);
m_tip[0].SetTipTextColor(RGB(0,0,255));
//设定文字的颜色
m_tip[0].SetDelayTime(150);
//设定提示文字在控件上停留的时间
3、重载CTipTestDlg::PreTranslateMessage(MSG* pMsg)函数,增加如下代码: if(m_tip[0].m_hWnd!=NULL)
m_tip[0].RelayEvent(pMsg);
//如果m_tip[0]句柄不为空,就从主窗口中捕获消息,如WM_MOUSEMOVE,WM_LBUTTONDOWN等消息\
if(m_tip[1].m_hWnd!=NULL)
m_tip[1].RelayEvent(pMsg);
4、捕获主窗口的WM_MOUSEMOVE消息,在CTipTestDlg::OnMouseMove(UINT nFlags, CPoint point)函数中增加如下代码: m_tip[0].UpdateTipText( VC知识库欢迎你! ,pSub[0]);
//鼠标在相应的控件上移动时显示提示文字
m_tip[1].UpdateTipText(
,pSub[1]);
17.删除文件夹// 删除文件夹及其所有内容
void CBaseDoc::RemoveFolder(const CString &strPathName)
CString path = strPathN
if (path.Right(1) != _T( \\ ))
path += _T( \\ );
path += _T( *.* );
BOOL res = ff.FindFile(path);
while (res)
res = ff.FindNextFile(); // 是文件时直接删除
if (!ff.IsDots() && !ff.IsDirectory())
DeleteFile(ff.GetFilePath());
else if (ff.IsDots())
else if (ff.IsDirectory())
path = ff.GetFilePath();
// 是目录时继续递归,删除该目录下的文件
RemoveFolder(path); ::RemoveDirectory(path);
18.消息映射有对话框A,B从A中发消息给B然后B处理。准备工作,先定义消息,如下
#define WM_B_NOTIFY WM_USER + 300
首先,必须将B的对话框句柄传送给A,暂时叫m_hWndB;在A的发送消息的地方这样写:::SendMessage( m_hWndB,WM_B_NOTIFY,TRUE,NULL );
这样A中的处理就完了,下面说B 中的首先定义消息处理函数,如下void B::ModiNotify( WPARAM wParam, LPARAM lParam )
MessageBox( 小样,我就不信,搞不定你! );
然后加消息隐射,如下:BEGIN_MESSAGE_MAP(CB, CDialog)
//{{AFX_MSG_MAP(CRPServerDlg)
ON_MESSAGE( WM_B_NOTIFY,ModiNotify )
//}}AFX_MSG_MAP END_MESSAGE_MAP()
19.给从CWnd派生的窗口添加滚动条ModifyStyle(0,WS_VSCROLL);
20. SetWindowPos函数功能:该函数改变一个子窗口,弹出式窗口式顶层窗口的尺寸,位置和Z序。子窗口,弹出式窗口,及顶层窗口根据它们在屏幕上出现的顺序排序、顶层窗口设置的级别最高,并且被设置为Z序的第一个窗口。      函数原型:BOOL SetWindowPos(HWN hWnd,HWND hWndlnsertAfter,int X,int Y,int cx,int cy,UNIT.Flags);      参数: hWnd:窗口句柄。 hWndlnsertAfter:在z序中的位于被置位的窗口前的窗口句柄。该参数必须为一个窗口句柄,或下列值之一: HWND_BOTTOM:将窗口置于Z序的底部。如果参数hWnd标识了一个顶层窗口,则窗口失去顶级位置,并且被置在其他窗口的底部。 HWND_DOTTOPMOST:将窗口置于所有非顶层窗口之上(即在所有顶层窗口之后)。如果窗口己经是非顶层窗口则该标志不起作用。 HWND_TOP:将窗口置于Z序的顶部。 HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。      查g看该参数的使用方法,请看说明部分。 x:以客户坐标指定窗口新位置的左边界。 Y:以客户坐标指定窗口新位置的顶边界。 cx:以像素指定窗口的新的宽度。 cy:以像素指定窗口的新的高度。 uFlags:窗口尺寸和定位的标志。该参数可以是下列值的组合: SWP_ASNCWINDOWPOS:如果调用进程不拥有窗口,系统会向拥有窗口的线程发出需求。这就防止调用线程在其他线程处理需求的时候发生死锁。 SWP_DEFERERASE:防止产生WM_SYNCPAINT消息。 SWP_DRAWFRAME:在窗口周围画一个边框(定义在窗口类描述中)。 SWP_FRAMECHANGED:给窗口发送WM_NCCALCSIZE消息,即使窗口尺寸没有改变也会发送该消息。如果未指定这个标志,只有在改变了窗口尺寸时才发送WM_NCCALCSIZE。 SWP_HIDEWINDOW;隐藏窗口。 SWP_NOACTIVATE:不激活窗口。如果未设置标志,则窗口被激活,并被设置到其他最高级窗口或非最高级组的顶部(根据参数hWndlnsertAfter设置)。 SWP_NOCOPYBITS:清除客户区的所有内容。如果未设置该标志,客户区的有效内容被保存并且在窗口尺寸更新和重定位后拷贝回客户区。 SWP_NOMOVE:维持当前位置(忽略X和Y参数)。 SWP_NOOWNERZORDER:不改变z序中的所有者窗口的位置。 SWP_NOREDRAW:不重画改变的内容。如果设置了这个标志,则不发生任何重画动作。适用于客户区和非客户区(包括标题栏和滚动条)和任何由于窗回移动而露出的父窗口的所有部分。如果设置了这个标志,应用程序必须明确地使窗口无效并区重画窗口的任何部分和父窗口需要重画的部分。 SWP_NOREPOSITION;与SWP_NOOWNERZORDER标志相同。 SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。 SWP_NOSIZE:维持当前尺寸(忽略cx和Cy参数)。 SWP_NOZORDER:维持当前Z序(忽略hWndlnsertAfter参数)。 SWP_SHOWWINDOW:显示窗口。   返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。若想获得更多错误消息,请调用GetLastError函数。   备注:如果设置了SWP_SHOWWINDOW和SWP_HIDEWINDOW标志,则窗口不能被移动和改变大小。如果使用SetWindowLoog改变了窗口的某些数据,则必须调用函数SetWindowPos来作真正的改变。使用下列的组合标志:SWP_NOMOVEISWP_NOSIZEISWP_FRAMECHANGED。   有两种方法将窗口设为最顶层窗口:一种是将参数hWndlnsertAfter设置为HWND_TOPMOST并确保没有设置SWP_NOZORDER标志;另一种是设置窗口在Z序中的位置以使其在其他存在的窗口之上。当一个窗口被置为最顶层窗口时,属于它的所有窗口均为最顶层窗口,而它的所有者的z序并不改变。   如果HWND_TOPMOST和HWND_NOTOPMOST标志均未指定,即应用程序要求窗口在激活的同时改变其在Z序中的位置时,在参数hWndinsertAfter中指定的值只有在下列条件中才使用:   在hWndlnsertAfter参数中没有设定HWND_NOTOPMOST和HWND_TOPMOST标志。   由hWnd参数标识的窗口不是激活窗口。   如果未将一个非激活窗口设定到z序的顶端,应用程序不能激活该窗口。应用程序可以无任何限制地改变被激活窗口在Z序中的位置,或激活一个窗口并将其移到最高级窗口的顶部或非最高级窗口的顶部。   如果一个顶层窗口被重定位到z序的底部(HWND_BOTTOM)或在任何非最高序的窗口之后,该窗口就不再是最顶层窗口。当一个最顶层窗口被置为非最顶级,则它的所有者窗口和所属者窗口均为非最顶层窗口。   一个非最顶端窗口可以拥有一个最顶端窗口,但反之则不可以。任何属于顶层窗口的窗口(例如一个对话框)本身就被置为顶层窗口,以确保所有被属窗口都在它们的所有者之上。   如果应用程序不在前台,但应该位于前台,就应调用SetForegroundWindow函数来设置。 Windows CE:如果这是一个可见的顶层窗口,并且未指定SWP_NOACTIVATE标志,则这个函数将激活窗口、如果这是当前的激活窗口,并且指定了SWP_NOACTIVATE或SWP_HIDEWINDOW标志,则激活另外一个可见的顶层窗口。   当在这个函数中的nFlags参数里指定了SWP_FRAMECHANGED标志时,WindowsCE重画窗口的整个非客户区,这可能会改变客户区的大小。这也是重新计算客户区的唯一途径,也是通过调用SetwindowLong函数改变窗口风格后通常使用的方法。 SetWindowPos将使WM_WINDOWPOSCHANGED消息向窗口发送,在这个消息中传递的标志与传递给函数的相同。这个函数不传递其他消息。 Windows CE 1.0不支持在hWndlnsertAber参数中的HWND_TOPMOST和HWND_NOTOPMOST常量。 Windows CE1.0不支持在fuFags参数中的SWP_DRAWFRAME和SWP_NOCOPYBITS标志。   速查:Windows NT:3.1以上版本;Windows:95以上版本;Windows CE:1.0以上版本;头文件:winuser.h库文件:eser32lib。
阅读(...) 评论()}

我要回帖

更多关于 c 未定义标识符 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信