社区
Web 开发
帖子详情
如何实现关闭一个弹出窗口,并传参给另一个窗口
sasa_sasa
2003-10-16 02:24:33
我打开一个弹出窗口显示 window.open("change_content.jsp?courseid="+courseid,"","width=450,height=300,left=255,top=100,scrollbars=yes");
然后,我要关闭这个窗口,并传参给其父窗口/;或如何使其父窗口刷新?????
...全文
219
7
打赏
收藏
如何实现关闭一个弹出窗口,并传参给另一个窗口
我打开一个弹出窗口显示 window.open("change_content.jsp?courseid="+courseid,"","width=450,height=300,left=255,top=100,scrollbars=yes"); 然后,我要关闭这个窗口,并传参给其父窗口/;或如何使其父窗口刷新?????
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
希偌
2003-10-16
打赏
举报
回复
不出现的话,加上
opener=null;
opener.document=null;
lsmh2000
2003-10-16
打赏
举报
回复
小弟现丑了,刚刚经过测试
主窗口为 1.htm 内容如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>主窗口</title>
<script>
function selectclass() {
window.open("2.htm","2","width=365,height=285,scrollbars=no,menubar=no,toolbar=no");
}
</script>
</head>
<body>
<form name="form1" method="post" action="">
<p>
<input type="text" name="aa" readonly="true" style="background:#faf0e0;">
<input type="button" name="Submit2" value="..." onClick="selectclass();">
</p>
<p>
<textarea name="textarea" cols="75" rows="8"></textarea>
</p>
<p>
<input type="submit" name="Submit" value="提交">
</p>
</form>
</body>
</html>
弹出窗口为 2.htm 内容如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>弹出选择窗口</title>
</head>
<body>
<form name="form2" method="post" action="">
返回值:
<input type="text" name="cc">
<input type="button" name="Submit" value="确认" onClick="window.opener.document.form1.aa.value=this.form.cc.value;window.close();">
</form>
</body>
</html>
看看可以不?
sasa_sasa
2003-10-16
打赏
举报
回复
window.close();
opener.location.reload();
这个方法可以实现/ 但是每次总是弹出一个提示窗口,选择是否刷新/ 能不能 不出现此窗口/
caina3
2003-10-16
打赏
举报
回复
opener.location.href="父窗口.jsp?你要传的参数";
window.close();
opener.location.reload();
比特灵
2003-10-16
打赏
举报
回复
var opWin = window.open("change_content.jsp?courseid="+courseid,"","width=450,height=300,left=255,top=100,scrollbars=yes");
1,关闭这个窗口:
在自身关闭window.close();
在其父窗口关闭:opWin.close();
2,传参给父窗口:parent.参数名 = xxx;
3,关闭父窗口:parent.close();
walkfish
2003-10-16
打赏
举报
回复
// 父窗口刷新
self.parent.location.reload();
//或者放弃window.open使用window.showModalDialog打开新窗口
//在关闭窗口的时候
window.returnValue = …;
希偌
2003-10-16
打赏
举报
回复
在打开的change_content.jsp里使用javascript
window.close();
opener.location.reload();
就可以关闭打开的窗口并刷新父窗口了
js showModalDialog
弹出
窗口
实例详解
showModalDialog:模式
窗口
, 一种很特别的
窗口
,当它打开时,后面的父
窗口
的活动会停止,除非当前的模式子
窗口
关闭
了, 才能操作父
窗口
.在做网页Ajax开发时,我们应该有时会用到它来
实现
表单的填写, 或做类似网上答题的
窗口
. 它的特点是,
传参
很方便也很强大,可直接调用父
窗口
的变量和方法. 使用方法: vReturnValue = window.showModalDialog(sURL [, vArguments] [,sFeatures]) 参数说明: sURL– 必选参数,类型:字符串。用来指定对话框要显示的文档的URL。 vArguments– 可选参数,类型:变
Qt记事本功能齐全,主要
实现
打开、新建、保存、另存为、查找、居中、字体、颜色、剪切、复制、粘贴等功能
运用Qt开发工具来
实现
一个
记事本,用户图形界面操作,通过Qt提供的图形库来设计记事本的管理、应用基本
窗口
,主要
实现
打开、新建、保存、另存为、查找、居中、字体、颜色等功能设计,同时在软件内部
实现
对于这些功能的支持和
实现
。还有对用户剪切、复制、粘贴、等功能的支持 核心代码讲解 1、打开文件功能 void MainWindow::on_action_2_triggered() { QString filename = QFileDialog::getOpenFileName(this); loadFile(filename); } 打开文件on_action_2_triggered()通过转到槽
实现
首先定义
一个
Qstring类型的filename让它获取你文件名,其次寻找它的本地连接。 3、保存文件功能 void MainWindow::on_action_3_triggered() { if(isSaved){ saveFile(curFile); } else{ do_file_SaveAS(); } } 保存文件功能on_action_3_triggered()通过转到槽
实现
,先判断bool型的isSaved是否是正确的,如果错则保存当前文件,否则执行另存为。 5、
关闭
功能 void MainWindow::on_action_5_triggered() { if(close){ QMessageBox::information(this,"提示","文件尚未保存,
关闭
"); }else{ ui->textEdit->close(); } }
关闭
功能on_action_5_triggered()先对文本进行判断是否是
关闭
的,如果是错
弹出
对话框提示消息文件尚未保存,
关闭
,否则对文档进行
关闭
11、查找功能 //查找 void MainWindow::close_findhangshu() { ui->gridLayoutWidget->close(); } close_findhangshu()对查找对话框进行
关闭
函数。 void MainWindow::on_action_11_triggered() { QDialog *closefind=new QDialog(this); QDialog *findDlg=new QDialog(this); find_textLineEdit=new QLineEdit(findDlg); QPushButton *find_Bth=new QPushButton(tr("查找下
一个
"),findDlg); QPushButton *close_find=new QPushButton(tr("
关闭
"),closefind); ui->gridLayout->addWidget(find_textLineEdit); ui->gridLayout->addWidget(find_Bth); ui->gridLayout->addWidget(close_find); connect(find_Bth,SIGNAL(clicked()),this,SLOT(show_findText())); connect(close_find,SIGNAL(clicked()),this,SLOT(close_findhangshu())); } 查找功能on_action_11_triggered()函数通过转到槽
实现
下面部分:先定义两个QDialog类型 指针变量*closefind和*findDlg,对它们进行新创建空间, find_textLineEdit=new QLineEdit(findDlg);新建
一个
空间对QlineEdit它进行
传参
,将findDlg传入目的是查找在文档中对应的文字,QPushButton *find_Bth=new QPushButton(tr("查找下
一个
"),findDlg);QPushButton *close_find=new QPushButton(tr("
关闭
"),closefind);这两个代码作用相同定义两个Qpubutton当点击查找功能
弹出
对话框时在对话框中
实现
查找下
一个
和
关闭
connect(find_Bth,SIGNAL(clicked()),this,SLOT(show_findText()));connect(close_find,SIGNAL(clicked()),this,SLOT(close_findhangshu()));点击查找下
一个
按钮时对它进行连接,执行show_findText()函数中的查找操作,如果点击
关闭
执行上述所说的close_findhangshu()
关闭
对话框操作 void MainWindow:: show_findText() { QString findText=find_textLineEdit->text(); if(!ui->textEdit->find(findText,QTextDocument::FindBackward)) { QMessageBox::warning(this,tr("查找"),tr("找不到 %1").arg(findText)); } } show_findText()此函数先定义QString类型 findText值,对文本进行扫描,如果文本不能找到找到则提示找不到。 本人也只是
一个
学生,记得点赞哦!
zDialog
弹出
框-内附使用说明及demo
代替window.open、window.alert、window.confirm;提供良好的用户体验; 水晶质感,设计细腻,外观漂亮; 兼容ie6/7/8、firefox2/3、Opera;
弹出
框在ie6下不会被select控件穿透; 无外部css文件,引用Dialog.js即可使用; 对iframe下的应用作了充分考虑,适合复杂的系统应用; Dialog显示的内容(三种):1、指向
一个
URL的iframe
窗口
;2、页面内隐藏的元素中的html内容;3、直接输出一段html内容; 按ESC键可
关闭
弹出
框;
MFC的程序框架剖析
什么是句柄? 句柄,是整个Windows编程的基础。
一个
句柄是指使用的
一个
唯一的整数值,即
一个
4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类对象中的不同的实例,诸如,
一个
窗口
,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是
一个
指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不用在I/O文件中,它是毫无用处的。 句柄是Windows用来标志应用程序中建立的或是使用的唯一整数,Windows使用了大量的句柄来标志很多对象。 一、MFC AppWizard 1、MFC(Microsoft Foundation Class,微软基础类库)是微软为了简化程序员的开发工作所开发的一套C++ 类的集合,是一套面向对象的函数库,以类的方式提供给用户使用 2、MFC AppWizard是
一个
辅助我们生成源代码的向导工具,它可以帮助我们自动生成基于MFC框架的源代码 二、基于MFC的程序框架剖析 1、MFC程序的ClassView标签页(图) 2、继承关系 (1)CMainFrame继承于CFrameWnd (2)CTestApp继承于CWinApp (3)CTestDoc继承于CDocument (4)CTestView继承于CView 注:CFrameWnd和CView都继承于CWnd 3、CWnd类是MFC中
一个
非常重要的类,它封装了与
窗口
相关的操作 4、MFC类的简化组织结构图(图) 5、MFC程序也有
一个
WinMain函数,程序是在编译时,由链接器将它链接到程序中 6、MFC程序具有
一个
CTestApp类的全局对象theApp,在MFC程序运行时,程序执行的顺序为:theApp全局对象定义 处->CTestApp构造函数->WinMain函数 7、对于普通的VC++控制台程序,无论全局变量还是全局对象,程序运行时,在加载main函数之前,就已经为它们 分配了内存空间。对于
一个
全局对象来说,此时就会调用该对象的构造函数,构造该对象,并进行初始化操作 8、实例句柄与全局对象 (1)对于Win32 SDK程序,应用程序的实例是由实例句柄(WinMain函数的hInstance参数)来标识的 (2)对于MFC程序,应用程序的实例是由全局对象(每
一个
MFC程序有且仅有
一个
从应用程序类CWinApp派生的类, 如CTestApp,它实例化theApp全局对象)来标识的 9、基类构造函数中this指针的指向问题 在构造子类对象时,会自动调用父类的构造函数,此时在父类的构造函数中的this指针所指向的是子类对象地址 10、AfxWinMain函数 MFC程序的WinMain函数是通过调用AfxWinMain函数来完成它的功能的 注:Afx前缀的函数代表应用程序框架(Application Framework)函数,它们可以在程序的任何地方被调用 11、CTestApp::InitInstance函数 在AfxWinMain函数中,通过调用InitInstance函数来完成MFC内部管理方面的工作 12、AfxEndDeferRegisterClass函数 MFC提供了一些默认的标准
窗口
类,我们只需要选择所需的
窗口
类就行。然后,调用AfxEndDeferRegisterClass 函数来注册
窗口
类 13、CMainFrame::PreCreateWindow函数 MFC程序具有两个
窗口
(框架
窗口
和视类
窗口
),在框架
窗口
产生之前会调用PreCreateWindow函数 14、CWnd::CreateEx函数 在MFC程序中,
窗口
的创建是由CreateEx函数
实现
的 15、CWnd::CreateWindowEx函数 主要作用是当修改了CreateEx函数的CREATESTRUCT参数时,CreateWindowEx函数会根据参数发生的相应变化来创 建
一个
符合我们要求的
窗口
注:MFC中后缀名为Ex的函数都是扩展函数 16、CMainFrame::ShowWindow函数和CMainFrame::UpdateWindow函数 用于显示应用程序框架
窗口
和更新这个
窗口
17、CWinThread::Run函数和CWinThread::PumpMessage函数 用于完成消息循环 18、DefWindowProc函数 默认的
窗口
过程,但MFC程序对消息的处理实际上是通过消息映射机制来完成的 19、MFC程序的运行过程 (1)首先利用全局应用程序对象theApp启动应用程序 (2)调用全局应用程序对象的构造函数,从而就会调用其基类CWinApp的构造函数,以完成应用程序的一些初始化 (3)进入WinMain函数 (4)进入消息循环 20、MFC程序的主要过程 theApp-> CTestApp::CTestApp构造函数-> CWinApp::CWinApp构造函数-> _tWinMain(WinMain函数的宏)-> AfxWinMain函数-> CTestApp::InitInstance函数-> AfxEndDeferRegisterClass函数-> CMainFrame::PreCreateWindow函数-> CFrameWnd::PreCreateWindow函数-> AfxDeferRegisterClass(AfxEndDeferRegisterClass函数的宏)-> CFrameWnd::Create函数-> CWnd::CreateEx函数-> CMainFrame::PreCreateWindow函数-> CWnd::CreateEx函数-> CMainFrame::ShowWindow函数-> CMainFrame::UpdateWindow函数-> CWinThread::Run函数-> CWinThread::PumpMessage函数 21、框架
窗口
(整个应用程序外框所包括的部分)是视类
窗口
(框架
窗口
中空白的地方)的
一个
父
窗口
22、MFC提供了
一个
文档/视类的结构,文档是指CDocument类,视类是指CView类。前者用于数据的存储和加载, 后者用于数据的显示和修改 23、框架对象、文档对象和视类对象是通过
一个
单文档模板指针来有机地组织在一起,并利用AddDocTemplate函数 把这个单文档模板添加到文档模板中,从而把这三个类组织成为
一个
整体 24、MFC程序的CAboutDlg类继承于CDialog类,用于为用户提供一些与程序相关的帮助信息 三、
窗口
类、
窗口
类对象与
窗口
1、以“::”开始的函数是
一个
全局函数,表示调用的是Platform SDK的函数 2、如果我们
关闭
了
一个
窗口
,这个
窗口
就销毁了,那么该
窗口
对应的C++
窗口
类对象销毁了吗? (1)当
一个
窗口
销毁时,它会调用CWnd::DestroyWindow函数,该函数销毁
窗口
后,将CWnd::m_hWnd设为NULL (2)
窗口
的生命周期和C++
窗口
类对象的声明周期不是一致的。当
一个
窗口
销毁时,与C++
窗口
类对象没有关系,它 们之间的纽带仅仅在于这个C++
窗口
类内部的成员变量m_hWnd,该变量保存了与这个C++
窗口
类对象相关的哪个
窗口
的句柄 (3)但是,当C++
窗口
类对象销毁时,与之相关的
窗口
也将销毁,因为它们之间的纽带m_hWnd已经断了 3、示例---在
窗口
中显示按钮 (1)CButton按钮类继承于CWnd (2)对于
一个
CButton对象,在定义之后就可以使用了;但是,如果要显示这个按钮的话,还需调用 CButton::Create函数,把按钮
窗口
与CButton对象关联起来 (3)MFC程序的
窗口
创建时都会产生WM_CREATE消息,该消息通过OnCreate函数来捕获。对于框架
窗口
来说,MFC直 接把OnCreate函数提供到了CMainFrame中;而在视类
窗口
中没有提供该函数,如需使用,要用户自行添加 (4)通常对MFC程序的操作,都是在CTestView视类
窗口
中进行的 (5)在
窗口
创建之后,要显示该
窗口
可以通过调用ShowWindow函数或指定
窗口
风格为WS_VISIBLE来
实现
(6)
实现
过程 A:在CTestView类中,添加CButton类型的私有成员m_btn B:在CTestView类中,添加WM_CREATE消息的OnCreate处理函数 C:在CTestView类中,通过GetParent函数可以获得CMainFrame框架
窗口
对象的指针 D:
实现
一(在视类
窗口
中通过ShowWindow函数显示按钮) int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... m_btn.Create("按钮",WS_CHILD|BS_DEFPUSHBUTTON,CRect(0,0,100,100),this,123); m_btn.ShowWindow(SW_SHOWNORMAL); return 0: } E:
实现
二(在视类
窗口
中通过WS_VISIBLE风格显示
窗口
) int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... m_btn.Create("按钮",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,CRect(0,0,100,100),this,123); return 0: } F:
实现
三(在框架
窗口
中显示按钮) int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... m_btn.Create("按钮",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,CRect(0,0,100,100),GetParent(),123); return 0: } 即便是基于MFC的应用程序,建立
窗口
类也是会遵循如下的过程: 设计
窗口
类->注册
窗口
类->生成
窗口
->显示
窗口
->更新
窗口
->消息循环->消息路由到
窗口
过程函数处理。下面就剖析一下在MFC中是如何完成上述过程的。 (1)每个应用程序都有且仅有
一个
应用类的全局变量theApp,全局变量先于WinMain函数进行处理。 (2)WinMain函数体在APPMODUL.CPP文件中,定义如下: extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } 其中#define _tWinMain WinMain (3)AfxWinMain函数体在WINMAIN.CPP文件中,里面有如下两句话: CWinThread* pThread = AfxGetThread(); CWinApp* pApp = AfxGetApp(); 其实这里得到的这两个指针都是指向全局的对象theApp的; 接下来有函数调用pThread->InitInstance(),根据多态性,会调用CXXXApp类中的InitInstance()函数。该函数很重要,在对该函数的调用中就会完成:设计
窗口
类->注册
窗口
类->生成
窗口
->显示
窗口
->更新
窗口
。 接下来,该函数中会继续调用pThread->Run(),这就完成了:消息循环->消息路由到
窗口
过程函数处理。 (4)进入CXXXApp::InitInstance()函数体中,对于单文档应用程序,调用ProcessShellCommand(cmdInfo),通过调用该函数就会完成:设计
窗口
类->注册
窗口
类->生成
窗口
。 再接下来就会调用m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();这就完成了:显示
窗口
->更新
窗口
。 (5)在函数CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)中会进入到如下的case分支:case CCommandLineInfo::FileNew: if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL)) (6)进入函数CCmdTarget::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo),调用_AfxDispatchCmdMsg(this, nID, nCode, lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo); (7)进入函数AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode, AFX_PMSG pfn, void* pExtra, UINT nSig, AFX_CMDHANDLERINFO* pHandlerInfo),调用 case AfxSig_vv: // normal command or control notification ASSERT(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED ASSERT(pExtra == NULL); (pTarget->*mmf.pfn_COMMAND)(); (8)进入CWinApp::OnFileNew(),调用m_pDocManager->OnFileNew();这个函数很特殊,它本身是个消息响应函数,当我们点击ID为ID_FILE_NEW的菜单时,会产生
一个
命令消息,由于命令消息可以被CCmdTarget类及其派生类来捕获,而CWinApp是从CCmdTarget派生出来的,因此可以捕获这个消息。当应用程序创建完成并成功显示后,当我们点击文件菜单下的新建菜单项时,就会首先进入这个函数,然后再依次执行下去,最后就会执行到pDocument->OnNewDocument()中,往往我们会对这个函数不解,不知道它为什么会响应ID_FILE_NEW的命令消息,至此真相大白了。顺便说一句,为什么程序在刚启动的时候,我们并没有点击菜单项,为什么会自动的产生这个消息呢?这是因为在CXXXXApp::InitInstance()函数中有“CCommandLineInfo cmdInfo;”这个类的构造函数是这样的:CCommandLineInfo::CCommandLineInfo() { m_bShowSplash = TRUE; m_bRunEmbedded = FALSE; m_bRunAutomated = FALSE; m_nShellCommand = FileNew; },因此就会在第(5)步骤的时候进入到“case CCommandLineInfo::FileNew:”这个分支中,就相当于产生了这样
一个
FileNew的消息。同理对于ID为ID_FILE_OPEN(在CWinApp::OnFileOpen()中响应)、ID_FILE_SAVE(在CDocument::OnFileSave()中响应)等等在MFC向导为我们生成的单文档类中找不到消息响应的入口时,其实都是在基类CWinApp或者CDocument类中进行了响应。对于CXXXXDoc::Serialize(CArchive& ar)函数也是通过ID_FILE_SAVE和ID_FILE_OPEN产生命令消息后就行响应从而才调用该函数的。 (9)进入CDocManager::OnFileNew(),CDocManager类有
一个
成员变量是CPtrList m_templateList;该变量保存了
一个
文档模版链表指针,在CDocManager::OnFileNew()函数体中会调用CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();得到链表中的头,也就是第
一个
文档模版,后面就会用得到的这个指针去调用pTemplate->OpenDocumentFile(NULL);紧接着就会有
一个
判断,用来确定该链表中是否只有一项,如果链表中保存了多个文档模版,则会
弹出
一个
对话框,来让我们选择到底是使用哪一套文档模版来构建应用程序,相信大家也都见到过这种情况吧。对了,还有一点要说明的是:pTemplate是
一个
CDocTemplate的指针,但接下来程序为什么会进入到CSingleDocTemplate::OpenDocumentFile的函数体内呢,这是因为CDocTemplate类中的OpenDocumentFile函数被定义为纯虚函数,而CSingleDocTemplate类又是从CDocTemplate类派生出来的,并且
实现
了该函数,因此就会进入到子类的函数体中了。 (10)进入CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, BOOL bMakeVisible),先调用CreateNewDocument()创建文档类,再调用pFrame = CreateNewFrame(pDocument, NULL);创建框架类和视图类,从这里也可以看出MFC体系结构中文档、框架、视图“三位一体”的模式,在这
一个
函数中同时创建三个类;再会调用pDocument->OnNewDocument();因此就会进入到子类的文档类中的pDocument->OnNewDocument()中了。 (11)进入CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther),调用if (!pFrame->LoadFrame(m_nIDResource, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles NULL, &context)) (12)进入BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext),调用VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)); (13)进入BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister),该函数内部就完成了:设计
窗口
类->注册
窗口
类。MFC通过给我们提供好一些已经订制好的
窗口
类,我们不需要自己再设计
窗口
类,只需要到那些订制好的
窗口
类“仓库”中寻找一种适合我们需要的
窗口
类就可以了,然后通过AfxRegisterClass函数注册
窗口
类。还需要说明的是,再后续的跟踪过程中,我们会发现还会进入到AfxEndDeferRegisterClass函数中进行设计和注册
窗口
类,这主要是因为单文档应用程序比较特殊,它提前通过这样的一种途径进行了
窗口
类的设计和注册步骤,其实是应该在BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)函数的调用中完成
窗口
类的设计和注册的,这一点我们要清楚,也就是说设计和注册
窗口
类的正宗发源地应该是PreCreateWindow(CREATESTRUCT& cs)。此外,我们还会注意到在该函数体的前部分有一语句为“wndcls.lpfnWndProc = DefWindowProc;”因此所有
窗口
类的
窗口
过程函数都是DefWindowProc,这一点在后面的跟踪中可以看到,每次生成
窗口
之后都会调用几次DefWindowProc函数。也就是说MFC都是让我们采用默认的
窗口
过程函数,这并不是说我们因此就不能使用自己的
窗口
过程函数
实现
个性化的消息处理了,MFC采用了一种基于消息映射的机制完成了消息个性化处理。 (14)回到BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)中,调用LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource); (15)进入LPCTSTR CFrameWnd::GetIconWndClass(DWORD dwDefaultStyle, UINT nIDResource),调用PreCreateWindow(cs); (16)进入BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs),调用CFrameWnd::PreCreateWindow(cs) (17)进入BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs),调用VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));又一次设计和注册
窗口
类 (18)回到BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)中,调用if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault, pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext)) (19)进入BOOL CFrameWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, LPCTSTR lpszMenuName, DWORD dwExStyle, CCreateContext* pContext),调用if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext)) (20)BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam),调用if (!PreCreateWindow(cs)) ,接下来调用HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);好了,终于让我们找到生成
窗口
的地方了——函数::CreateWindowEx! (21)进入int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct),调用if (CFrameWnd::OnCreate(lpCreateStruct) == -1) (22)进入int CFrameWnd::OnCreate(LPCREATESTRUCT lpcs),调用return OnCreateHelper(lpcs, pContext); (23)进入int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext* pContext),调用if (CWnd::OnCreate(lpcs) == -1) (24)进入_AFXWIN_INLINE int CWnd::OnCreate(LPCREATESTRUCT),调用return (int)Default(); (25)进入LRESULT CWnd::Default(),调用return DefWindowProc(pThreadState->m_lastSentMsg.message, pThreadState->m_lastSentMsg.wParam, pThreadState->m_lastSentMsg.lParam); (26)进入LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam),调用return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam); (27)回到int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext* pContext),调用if (!OnCreateClient(lpcs, pContext)) (28)进入BOOL CFrameWnd::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext),调用if (CreateView(pContext, AFX_IDW_PANE_FIRST) == NULL) (29)进入CWnd* CFrameWnd::CreateView(CCreateContext* pContext, UINT nID),调用if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), this, nID, pContext)) (30)进入BOOL CWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext),调用return CreateEx(0, lpszClassName, lpszWindowName, dwStyle | WS_CHILD, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), (HMENU)nID, (LPVOID)pContext); (31)进入BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam),重复生成框架类CMainFrame的过程来生成CXXXView,因为它也是
一个
窗口
类,因此也需要进行那一系列过程才能最终显示更新出来。 调用的顺序是这个样子的:PreCreateWindow(cs)->BOOL CXXXView::PreCreateWindow(CREATESTRUCT& cs)->CView::PreCreateWindow(cs)->VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));->::CreateWindowEx(...)->CWnd::DefWindowProc->::CallWindowProc(...)->...->CXXXView::OnCreate->CView::OnCreate->CWnd::OnCreate->... 写到这里,基本上就清楚了,中间的省略号表示的部分大多数都是在与
窗口
过程函数有关的,因为在生成
窗口
的时候需要响应一些消息,因此需要调用一些
窗口
过程函数,每次在调用::CreateWindowEx(...)函数后都会调用一些
窗口
过程函数,然后再去调用该
窗口
类对应的OnCreate函数,其实在调用OnCreate函数之前调用CreateWindowEx只是生成了
一个
窗口
,至于这个
窗口
里面要放置些什么东西,以及该如何装饰该
窗口
,则就需要由OnCreate来完成了,往往我们都会在OnCreate函数的后面(这样做是为了不影响
窗口
本身应该布置的格局)添加一些代码,创建我们自己的东西,比如我们通常会在CMainFrame类的OnCreate函数后面放置一些Create代码,来创建我们自己的可停靠的工具栏或者按钮之类的东西,当然我们也可以在CXXXView类的OnCreate函数的后面添加一些代码,来创建我们需要的东西,比如按钮之类的东西。在完成了从设计、注册到生成
窗口
的过程之后,往往还需要显示更新,有些时候,我们不必要每次都显示的调用CWnd的ShowWindow和UpdateWindow两个函数,我们可以在创建的时候,给
窗口
风格中添加WS_VISIBLE即可,因此有些时候会跟踪不到ShowWindow和UpdateWindow两个函数这两个函数,因为
窗口
在创建的时候就可见了。 总的来说,先初始化应用类,然后注册生成框架类,然后再注册生成视图类,然后注册生成视图类OnCreate函数后面用户添加的、用Create来准备创建的
窗口
,然后再注册生成框架类的OnCreate函数后面需要生成的m_wndToolBar、m_wndStatusBar以及我们自己添加的要创建的
窗口
类,最后在回到应用类的初始化的函数体中,调用框架类的显示和更新函数,然后再进入由框架类定义的
窗口
的消息循环中。 消息循环的过程是这个样子的: (1)调用int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)函数中的pThread->Run() (2)进入int CWinApp::Run(),调用return CWinThread::Run(); (3)进入int CWinThread::Run(),调用if (!PumpMessage()) (4)进入BOOL CWinThread::PumpMessage(),调用if (!::GetMessage(&m_msgCur, NULL, NULL, NULL)) (5)回到BOOL CWinThread::PumpMessage(),调用::TranslateMessage(&m_msgCur);::DispatchMessage(&m_msgCur); (6)回到int CWinThread::Run(),调用while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); (7)再重复(4)-(6)的步骤 下面给出int CWinThread::Run()中消息循环的部分代码: do { // pump message, but quit on WM_QUIT if (!PumpMessage()) return ExitInstance(); // reset "no idle" state after pumping "normal" message if (IsIdleMessage(&m_msgCur)) { bIdle = TRUE; lIdleCount = 0; } } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); 这段代码其实本质上与我们基于Win32 SDK手写的代码: //消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0)) { //简单的说,函数TranslateMessage就是把WM_KEYDOWN和WM_KEYUP翻译成WM_CHAR消息,没有该函数就不能产生WM_CHAR消息。 TranslateMessage(&msg); ::DispatchMessage(&msg); } 是一致的。 1,寻找WinMain人口: 在安装目录下找到MFC文件夹下的SRC文件夹,SRC下是MFC源代码。 路径:MFC|SRC|APPMODUL.CPP: _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } 注意:(#define _tWinMain WinMain) 2,对于全局对象或全局变量来说,在程序运行即WINMAIN函数加载的时候,已经为全局对象或全局变量分配了内存和赋初值。 所以:CTEApp theApp;->CTEApp ::CTEApp(){}->_tWinMain(){} 说明:每
一个
MFC程序,有且只有
一个
从WinApp类派生的类(应用程序类),也只有
一个
从应用程序类所事例化的对象,表示应用程序本身。在WIN32程序当中,表示应用程序是通过WINMAIN入口函数来表示的(通过
一个
应用程序的
一个
事例号这
一个
标识来表示的)。在基于MFC应用程序中,是通过产生
一个
应用程序对象,用它来唯一的表示了应用程序。 3,通过构造应用程序对象过程中调用基类CWinApp的构造函数,在CWinApp的构造函数中对程序包括运行时一些初始化工作完成了。 CWinApp构造函数:MFC|SRC|APPCORE.CPP CWinApp::CWinApp(LPCTSTR lpszAppName){...}//带参数,而CTEApp构造函数没有显式向父类
传参
,难道CWinApp()有默认参数?见下: (在CWinApp类定义中, CWinApp(LPCTSTR lpszAppName = NULL); ) 注意:CWinApp()函数中: pThreadState->m_pCurrentWinThread = this; pModuleState->m_pCurrentWinApp = this (this指向的是派生类CTEApp对象,即theApp) 调试:CWinApp::CWinApp();->CTEApp theApp;(->CTEApp ::CTEApp())->CWinApp::CWinApp()->CTEApp ::CTEApp()->_tWinMain(){} 4,_tWinMain函数中通过调用AfxWinMain()函数来完成它要完成的功能。(Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序)。 AfxWinMain()函数路径:MFC|SRC|WINMAIN.CPP: 在AfxWinMain()函数中: CWinApp* pApp = AfxGetApp(); 说明:pApp存储的是指向WinApp派生类对象(theApp)的指针。 //_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp() // { return afxCurrentWinApp; } 调用pThread->InitInstance() 说明:pThread也指向theApp,由于基类中virtual BOOL InitApplication()定义为虚函数,所以调用pThread->InitInstance()时候,调用的是派生类CTEApp的InitInstance()函数。 nReturnCode = pThread->Run(); 说明:pThread->Run()完成了消息循环。 5,注册
窗口
类:AfxEndDeferRegisterClass(); AfxEndDeferRegisterClass()函数所在文件:MFC|SRC|APPCORE.CPP BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister){...} 说明:设计
窗口
类:在MFC中事先设计好了几种缺省的
窗口
类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的
窗口
类。 调试:CWinApp::CWinApp();->CTEApp theApp;(->CTEApp ::CTEApp())->CWinApp::CWinApp()->CTEApp ::CTEApp()->_tWinMain(){}//进入程序 ->AfxWinMain();->pApp->InitApplication();->pThread->InitInstance()//父类InitInstance虚函数;->CTEApp::InitInstance()//子类
实现
函数;->AfxEndDeferRegisterClass(LONG fToRegister)//注册所选择的
窗口
类(出于文档管理,注册提前,正常的应在PreCreateWindow中进行注册)//之后进入创建
窗口
阶段(以下再不做调试) 6,PreCreateWindow()://主要是注册
窗口
类 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; return TRUE; } 说明: CFrameWnd::PreCreateWindow()函数所在文件:MFC|SRC|WINFRM.CPP BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) { if (cs.lpszClass == NULL) { VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)); //判断AFX_WNDFRAMEORVIEW_REG型号
窗口
类是否注册,如果没有注册则注册 cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background //把注册后的
窗口
类名赋给cs.lpszClass } if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4) cs.style |= FWS_PREFIXTITLE; if (afxData.bWin4) cs.dwExStyle |= WS_EX_CLIENTEDGE; return TRUE; } 其中: virtual BOOL PreCreateWindow(CREATESTRUCT& cs);//PreCreateWindow()是个虚函数,如果子类有则调用子类的。 #define VERIFY(f) ASSERT(f) #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass) define AFX_WNDFRAMEORVIEW_REG 0x00008 const TCHAR _afxWndFrameOrView[] = AFX_WNDFRAMEORVIEW;//WINCORE.CPP文件中,定义为全局数组。 //#define AFX_WNDFRAMEORVIEW AFX_WNDCLASS("FrameOrView") 7,创建
窗口
: Create()函数路径:MFC|SRC|WINFRM.CPP: CFrameWnd::Create(...){ ... CreateEx(...);//从父类继承来的,调用CWnd::CreateEx(). ... } CWnd::CreateEx()函数路径:MFC|SRC|WINCORE.CPP BOOL CWnd::CreateEx(...){ ... if (!PreCreateWindow(cs))//虚函数,如果子类有调用子类的。 { PostNcDestroy(); return FALSE; } ... HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams); ... } 说明:CreateWindowEx()函数与CREATESTRUCT结构体参数的对应关系,使我们在创建
窗口
之前通过可PreCreateWindow(cs)修改cs结构体成员来修改所要的
窗口
外观。PreCreateWindow(cs))//是虚函数,如果子类有调用子类的。 HWND CreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam ); typedef struct tagCREATESTRUCT { // cs LPVOID lpCreateParams; HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; int cy; int cx; int y; int x; LONG style; LPCTSTR lpszName; LPCTSTR lpszClass; DWORD dwExStyle; } CREATESTRUCT; 8,显示和更新
窗口
: CTEApp类,TEApp.cpp中 m_pMainWnd->ShowWindow(SW_SHOW);//显示
窗口
,m_pMainWnd指向框架
窗口
m_pMainWnd->UpdateWindow();//更新
窗口
说明: class CTEApp : public CWinApp{...} class CWinApp : public CWinThread{...} class CWinThread : public CCmdTarget { ... public: CWnd* m_pMainWnd; ... ... } 9,消息循环: int AFXAPI AfxWinMain() { ... // Perform specific initializations if (!pThread->InitInstance()){...} //完成
窗口
初始化工作,完成
窗口
的注册,完成
窗口
的创建,显示和更新。 nReturnCode = pThread->Run(); //继承基类Run()方法,调用CWinThread::Run()来完成消息循环 ... } //////////////////////////////////////////////////////////////// CWinThread::Run()方法路径:MFC|SRC|THRDCORE.CPP int CWinThread::Run() { ... // phase2: pump messages while available do//消息循环 { // pump message, but quit on WM_QUIT if (!PumpMessage())//取消息并处理 return ExitInstance(); ... } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); ... } 说明: BOOL PeekMessage(,,,,)函数说明 The PeekMessage function checks a thread message queue for a message and places the message (if any) in the specified structure. If a message is available, the return value is nonzero. If no messages are available, the return value is zero. ///////////////////////////////////////////////////////////// BOOL CWinThread::PumpMessage() { ... if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))//取消息 {...} ... // process this message if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur)) { ::TranslateMessage(&m_msgCur);//进行消息(如键盘消息)转换 ::DispatchMessage(&m_msgCur);//分派消息到
窗口
的回调函数处理(实际上分派的消息经过消息映射,交由消息响应函数进行处理。) } return TRUE; } 9,文档与视结构: 可以认为View类
窗口
是CMainFram类
窗口
的子
窗口
。 DOCument类是文档类。 DOC-VIEW结构将数据本身与它的显示分离开。 文档类:数据的存储,加载 视类:数据的显示,修改 10,文档类,视类,框架类的有机结合: 在CTEApp类CTEApp::InitInstance()函数中通过文档模板将文档类,视类,框架类的有机组织一起。 ... CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CTEDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CTEView)); AddDocTemplate(pDocTemplate);//增加到模板
Vue 中在新
窗口
打开页面并
传参
需求:
实现
在新
窗口
中打开页面,并传递参数,该参数不能显示在地址栏中,除非手动
关闭
该新
窗口
,否则传递给页面的参数不能丢失。 //打开新
窗口
并
传参
,参数不能显示在地址栏里面,不
关闭
窗口
一直刷新,参数一直有效 handleWindow() { var route = this.$router.resolve({ name: ‘Xterm’, }) //主要
实现
存储参数的功能 sessionStorage.setItem("ip", "1.1.1.1");
Web 开发
81,092
社区成员
341,716
社区内容
发帖
与我相关
我的任务
Web 开发
Java Web 开发
复制链接
扫一扫
分享
社区描述
Java Web 开发
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章