第八讲对话框.docx

上传人:b****3 文档编号:3807449 上传时间:2022-11-25 格式:DOCX 页数:13 大小:22.54KB
下载 相关 举报
第八讲对话框.docx_第1页
第1页 / 共13页
第八讲对话框.docx_第2页
第2页 / 共13页
第八讲对话框.docx_第3页
第3页 / 共13页
第八讲对话框.docx_第4页
第4页 / 共13页
第八讲对话框.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

第八讲对话框.docx

《第八讲对话框.docx》由会员分享,可在线阅读,更多相关《第八讲对话框.docx(13页珍藏版)》请在冰豆网上搜索。

第八讲对话框.docx

第八讲对话框

对话框

对话框是应用程序创建的用来获取用户输入的一个临时窗口。

应用程序一般用对话框来提示用户输入命令的附加信息。

如果有很多输入超出了菜单可以处理的程度,那么我们可以使用对话框来取得输入信息。

对话框的一般形式是包含多种子窗口控件的弹出式窗口,这些控件的大小和位置在程序资源描述文件的对话框模板中指定。

虽然程序员能够手工定义对话框模板,但是现在通常是在VisualC++DeveloperStudio中以交互式操作的方式设计的,然后由DeveloperStudio建立对话框模板。

当程序调用依据模板建立的对话框时,Windows系统负责建立弹出式对话框窗口和子窗口控件,并提供处理对话框消息(包括所有键盘和鼠标输入)的窗口过程。

完成这些功能的windows内部代码被称为对话框管理器。

Windows的内部对话框窗口消息处理程序所处理的许多消息也传递给程序员所编写程序中的函数,这个函数即是所谓的对话框过程或者对话过程。

对话过程与普通的窗口过程程序类似,但是也存在着一些重要区别。

一般来说,除了在建立对话框时初始化子窗口控件,处理来自子窗口控件的消息以及结束对话框之外,程序员不需要再给对话框过程增加其它功能。

对话过程通常不处理WM_PAINT消息,也不直接处理键盘和鼠标输入。

对话框的类型:

模态对话框:

在应用程序能继续运行之前,要求用户必须显式地提供信息或取消对话框,对话框不能在同一应用程序的其它窗口之间进行切换,把模态对话框与不输入附加信息就不能继续执行的命令一起使用。

非模态对话框:

允许用户提供信息并返回前一任务,但不关闭该对话框。

模态对话框通过调用单个函数就可以创建、执行它们的任务和销毁,因此比无模态对话框更容易管理。

无论是创建模态对话框还是非模态对话框,应用程序都必须提供一个对话框模板来描述对话框的样式和内容,并提供一个对话框过程来完成任务。

应用程序一般用DialogBox或CreateDialog函数来创建对话框。

DialogBox用来创建模态对话框,CreateDialog用来创建无模态对话框。

通用对话框:

为实现标准用户界面,提供统一、通用的功能,而实现的一组增强对话框;开发人员可以根据应用程序的特点,对已有的这些通用对话框进行定制扩展。

 

每一个对话框都有一个属主窗口,应用程序在创建对话框时应指定一个属主窗口。

若属主窗口被隐藏或销毁,对话框同时被隐藏或销毁。

一个对话框可以没有属主窗口,但不建议这样使用,例如一个模态对话框没有属主,Windows就不会使其他窗口无效,这样就达不到使用模态对话框的目的。

如果一个非模态对话框没有属主,那么当应用程序的其他窗口被隐藏或销毁时,Windows不会隐藏和销毁该对话框,这就要求应用程序完成特殊的处理工作,以便在合适的时机隐藏和销毁该对话框。

消息框:

消息框也是一个对话框,但是Windows完全控制了消息框的创建和管理。

这就意味着应用程序不用提供对话框模板和对话框过程。

应用程序在创建该对话框时还可以指定MB_SYSTEMMODA来弹出一个系统消息框,这个消息框会挂起所有运行中的应用程序,用来向用户提出严重警告等信息。

 

模态对话框:

模态对话框是一个弹出窗口,包含System菜单、标题栏和粗边界。

对于模态对话框WS_VISIBLE风格没有效果。

应用程序决不能创建一个具有WS_CHILD样式的模态对话框,具有这种风格的模式对话框将使自己无效,从而使应用程序不能继续。

应用程序调用DialogBox或者DialogBoxIndirect就可以创建模态对话框。

所不同处在于DialogBox要求一个模板资源名,而DialogBoxIndirect要求一个模板的内存对象句柄。

模态对话框一创建,Windows自动将它变成活动窗口。

属主窗口以及其子窗口都被变成无效的。

当模态对话框活动时,用户或应用程序都不应使属主窗口成为活动的。

为了处理模态对话框的消息,Windows启动一个临时消息环接管整个应用程序消息队列。

如果Windows收到一条明显不是对话框的消息,就把它发送给正确的窗口(非排队消息)。

如果发现一条WM_QUIT消息,则把它投递给应用程序的消息队列,以便使应用程序主消息环最终能够收到该消息。

只要应用程序的消息队列为空,Windows就把WM_ENTERIDLE消息发送给属主窗口,使得应用程序能够在对话框仍然存在的情况下进行后台任务处理。

但是这样并不理想,可以使用PeekMessage来交出控制权,也可以对对话框使用DS_NOIDLEMSG风格来禁止Windows发送该消息。

使用EndDialog来终止一个对话框,并且返回一个值来指明是否成功的完成了任务。

 

模态对话框的内部实现原理

DialogBox//#defineDialogBox…DialogBoxParam…

DialogBoxParam

逐层向上查找祖先窗口,直到找到一个具有popup或overlapped风格的窗

口作为父窗口

禁用父窗口//父窗口不再处理鼠标和键盘消息

CreateDialogParam//创建模态对话框(父、子窗口)

SetWindowWord(hwndDlg,DWL_ENDDIALOGCALLED,FALSE);//设置

私有数据

while(!

GetWindowWord(hwndDlg,DWL_ENDDIALOGCALLED)){//有自己的消

息环

GetMessage(&msg,NULL,0,0);

if(!

IsDialogMessage(hwndDlg,&msg)){

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

DestroyWindow(hwndDlg);//销毁窗口

 

结束模态对话框:

EndDialog

获取父窗口句柄

启用父窗口//父窗口继续处理鼠标和键盘消息

SetWindowLong(hwnd,DWL_ENDDIALOGCALLED,TRUE);//设置私有数据

SetWindowLong(hwnd,DWL_DLGRESULT,nResult);//设置返回值

 

模态对话框举例:

YoucreateamodaldialogboxbyusingtheDialogBoxfunction.Youmustspecifytheidentifierornameofadialogboxtemplateresourceandapointertothedialogboxprocedure.TheDialogBoxfunctionloadsthetemplate,displaysthedialogbox,andprocessesalluserinputuntiltheuserclosesthedialogbox.

Inthefollowingexample,theapplicationdisplaysamodaldialogboxwhentheuserclicksDeleteItemfromanapplicationmenu.Thedialogboxcontainsaneditcontrol(inwhichtheuserentersthenameofanitem)andOKandCancelbuttons.ThecontrolidentifiersforthesecontrolsareID_ITEMNAME,IDOK,andIDCANCEL,respectively.

Thefirstpartoftheexampleconsistsofthestatementsthatcreatethemodaldialogbox.Thesestatements,inthewindowprocedurefortheapplication'smainwindow,createthedialogboxwhenthesystemreceivesaWM_COMMANDmessagehavingtheIDM_DELETEITEMmenuidentifier.Thesecondpartoftheexampleisthedialogboxprocedure,whichretrievesthecontentsoftheeditcontrolandclosesthedialogboxuponreceivingaWM_COMMANDmessage.

Thefollowingstatementscreatethemodaldialogbox.Thedialogboxtemplateisaresourceintheapplication'sexecutablefileandhastheresourceidentifierDLG_DELETEITEM:

caseWM_COMMAND:

switch(LOWORD(wParam))

{

caseIDM_DELETEITEM:

if(DialogBox(hinst,

MAKEINTRESOURCE(DLG_DELETEITEM),

hwnd,(DLGPROC)DeleteItemProc)==IDOK)

{

//Completethecommand;szItemNamecontainsthe

//nameoftheitemtodelete.

}

else

{

//Cancelthecommand.

}

break;

}

return0L;

Inthisexample,theapplicationspecifiesitsmainwindowastheownerwindowforthedialogbox.Whenthesysteminitiallydisplaysthedialogbox,itspositionisrelativetotheupperleftcorneroftheownerwindow'sclientarea.TheapplicationusesthereturnvaluefromDialogBoxtodeterminewhethertoproceedwiththeoperationorcancelit.Thefollowingstatementsdefinethedialogboxprocedure.

charszItemName[80];//receivesnameofitemtodelete.

BOOLCALLBACKDeleteItemProc(HWNDhwndDlg,UINTmessage,WPARAMwParam,LPARAMlParam)

{

switch(message)

{

caseWM_COMMAND:

switch(LOWORD(wParam))

{

caseIDOK:

if(!

GetDlgItemText(hwndDlg,ID_ITEMNAME,

szItemName,80))

*szItemName=0;

//Fallthrough.

caseIDCANCEL:

EndDialog(hwndDlg,wParam);

returnTRUE;

}

}

returnFALSE;

}

Inthisexample,theprocedureusesGetDlgItemTexttoretrievethecurrenttextfromtheeditcontrolidentifiedbyID_ITEMNAME.TheprocedurethencallstheEndDialogfunctiontosetthedialogbox'sreturnvaluetoeitherIDOKorIDCANCEL,dependingonthemessagereceived,andtobegintheprocessofclosingthedialogbox.TheIDOKandIDCANCELidentifierscorrespondtotheOKandCancelbuttons.AftertheprocedurecallsEndDialog,thesystemsendsadditionalmessagestotheproceduretodestroythedialogboxandreturnsthedialogbox'sreturnvaluebacktothefunctionthatcreatedthedialogbox.

 

非模态对话框:

使用CreateDialog或CreateDialogIndirect创建非模态对话框。

这两个函数返回对话框的句柄。

非模态对话框既不使属主窗口无效,也不给他发送消息。

应用程序要负责为对话框捡取和分发输入消息(共用一个消息队列)。

为了允许用户用键盘移动到并选择控制框,应用程序必须调用IsDialogMessage来判断消息是否来自对话框。

应用程序通过DestroyWindow来销毁一个无模式对话框。

CreateDialog函数内部利用CreateWindowEx创建非模态对话框,然后向对话框窗口过程发送WM_INITDIALOG消息,如果在对话框模板中指定了WS_VISIBLE风格,CreateDialog函数就马上显示这个新创建的对话框,最后返回对话框的窗口句柄。

非模态对话框的内部实现原理

CreateDialog//#defineCreateDialog…CreateDialogParam…

CreateDialogParam

FindResource//在exe文件中查找并定位对话框模板

LoadResource

CreateDialogIndirectParam//根据内存块中的对话框模

//板创建父、子窗口

FreeResource

返回创建的对话框窗口句柄//注意与模态对话框的区别

修改创建此对话框线程的消息环

while(GetMessage(&msg,NULL,0,0))

{

if(hDlgModeless==0

&&!

IsDialogMessage(hDlgModeless,&msg))

{

if(!

TranslateAccelerator(hwnd,hAccel,&msg))

TranslateMessage(&msg);

DispatchMessage(&

}

}

非模态对话框的销毁

caseWM_CLOSE:

DestroyWindow();

hDlgModeless=NULL;

break;

对话框过程:

对话框过程类似窗口过程,但并不一样。

对话框过程处理一些程序设计者需要处理的消息,并返回TRUE,对于他不处理的消息,返回FALSE,由Windows传递给默认的窗口过程处理。

对话框过程不应当调用DefWindowProc。

绝大部分情况下,对话框过程通常只需要处理如下两种消息:

WM_INITDIALOG:

是对话框过程函数在对话框被显示之前接收到的消息,它是对话框过程函数接收到的第一个消息,用于完成初始化工作。

WM_COMMAND:

在对话框过程函数中处理来自子控件的消息。

非模态对话框举例:

YoucreateamodelessdialogboxbyusingtheCreateDialogfunction,specifyingtheidentifierornameofadialogboxtemplateresourceandapointertothedialogboxprocedure.CreateDialogloadsthetemplate,createsthedialogbox,andoptionallydisplaysit.Yourapplicationisresponsibleforretrievinganddispatchinguserinputmessagestothedialogboxprocedure.

Inthefollowingexample,theapplicationdisplaysamodelessdialogbox—ifitisnotalreadydisplayed—whentheuserclicksGoTofromanapplicationmenu.Thedialogboxcontainsaneditcontrol,acheckbox,andOKandCancelbuttons.Thedialogboxtemplateisaresourceintheapplication'sexecutablefileandhastheresourceidentifierDLG_GOTO.Theuserentersalinenumberintheeditcontrolandchecksthecheckboxtospecifythatthelinenumberisrelativetothecurrentline.ThecontrolidentifiersareID_LINE,ID_ABSREL,IDOK,andIDCANCEL.

Thestatementsinthefirstpartoftheexamplecreatethemodelessdialogbox.Thesestatements,inthewindowprocedurefortheapplication'smainwindow,createthedialogboxwhenthewindowprocedurereceivesaWM_COMMANDmessagehavingtheIDM_GOTOmenuidentifier,butonlyiftheglobalvariablehwndGotodoesnotalreadycontainavalidhandle.Thesecondpartoftheexampleistheapplication'smainmessageloop.TheloopincludestheIsDialogMessagefunctiontoensurethattheusercanusethedialogboxkeyboardinterfaceinthismodelessdialogbox.Thethirdpartoftheexampleisthedialogboxprocedure.TheprocedureretrievesthecontentsoftheeditcontrolandcheckboxwhentheuserclickstheOKbutton.TheproceduredestroysthedialogboxwhentheuserclickstheCancelbutton.

HWNDhwndGoto=NULL;//windowhandleofdialogbox

.

.

.

caseWM_COMMAND:

switch(LOWORD(wParam))

{

caseIDM_GOTO:

if(!

IsWindow(hwndGoto))

{

hwndGoto=CreateDialog(hinst,

MAKEINTRESOURCE(DLG_GOTO),

hwnd,(DLGPROC)GoToProc);

ShowWindow(hwndGoto,SW_SHOW);

}

break;

}

return0L;

Intheprecedingstatements,CreateDialogiscalledonlyifhwndGotodoesnotcontainavalidwindowhandle.Thisensuresthattheapplicationdoesnotdisplaytwodialogboxesatthesametime.Tosupportthismethodofchecking,thedialogproceduremustsethwndGototoNULLwhenitdestroysthedialogbox.

Themessageloopforanapplicationconsistsofthefollowingstatements:

BOOLbRet;

while((bRet=GetMessage(&msg,NULL,0,0))!

=0)

{

if(bRet==-1)

{

//handletheerrorandpossiblyexit

}

elseif(!

IsWindow(hwndGoto)||!

IsDialogMessage(hwndGoto,&msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

TheloopchecksthevalidityofthewindowhandleforthedialogboxandonlycallstheIsDialogMessagefunctionifthehandleisvalid.IsDialogMessageonlyprocessesthemessageifitbelongstothedialogbox.Otherwise,itreturnsFALSEandtheloopdispatchesthemessagetotheappropr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1