如何让基于对话框的程序一开始就隐藏呢?

Brierbird 2000-03-12 12:28:00
如题.
...全文
426 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
sodawater 2000-03-13
  • 打赏
  • 举报
回复
还有一个简单的办法把程序把在主程序文件里面
Brierbird 2000-03-13
  • 打赏
  • 举报
回复
这样是没用的。
marshell0 2000-03-13
  • 打赏
  • 举报
回复
in OniniDialog()
Excute ShowWindow(SW_SHOW)
Brierbird 2000-03-13
  • 打赏
  • 举报
回复
首先感谢诸位的帮助。
不过,还是有些问题:
(1)回rosement:在CDlgApp::InitInstance()中的最后一句return FALSE是不能删掉的,因为必须要有一个返回值,如果改为return TRUE,那么即便将Dialog关闭程序还是在程序管理器中存在。
(2)回amanne:谢谢提供托盘源程序。任务栏程序是不错。不过,这里并不是我想的真正效果。
(3)回jamesw:你指的是在哪一种模式下?
jamesw 2000-03-13
  • 打赏
  • 举报
回复
在InitInstance中设置个时钟,
然后OnTimer()中kill timer and showwindow(sw_hide)
酷点点 2000-03-13
  • 打赏
  • 举报
回复
我这里有一个DELPHI的任务栏实现方法(VC++的没找到:(),但和VC++的实现原理一样,只是OOP-PASCAL和C++的区别。你可以参考。变通。也可以找一下其它程序员网站。good lucky !怎样建立简单的任务栏应用程序:
资料来源:Internet
翻译:傅贵
日期:98.3.2
本页版主:傅贵,最后修改日期:98.3.2
Windows 95 和 Windows NT 4.0包含一个令人兴奋的特性:任务栏。这个通常位于区域任务条右面的区域能包含小的图标,这些图标能引出大的应用程序或者菜单。本篇文章主要讨论如何使用Delphi建立这样的应用程序。

在开始之前,请看下面的需要的接口方面的内容:

从技术方面来说,一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,相应Windows的消息来完成相应的功能。

Procedure RunTrayApplication;
Var Msg : TMsg;
Begin
CreateWindow;
AddTrayIcon;
While GetMessage(Msg,0,0,0) do Begin
TranslateMessage(Msg);
DispatchMessage(Msg);
End;
DeleteTrayIcon;
End;
你能看到:所有需要做的工作是创建一个窗口,注册一个图标到任务栏,设置它的消息循环,最后关闭它。当然,必须还有增加其他代码完成相应的功能,但是,它是真的不需要担心。
让我们从窗口的创建开始。实际上,这个窗口是不是能在任务栏上能见到的窗口。相应的,这个窗口只是处理消息循环、其它父类的工作。任务窗口(Windows 95 & NT)句柄创建消息(例如鼠标单击等)和将消息发到我们的窗口。

Procedure CreateWindow;
Var
WC : TWndClass;
W : hWnd;
Begin
With WC do Begin
Style := 0;
lpfnWndProc := @WndProc;
cbClsExtra := 0;
cbWndExtra := 0;
hIcon := 0;
hCursor := 0;
hbrBackground := 0;
lpszMenuName := nil;
lpszClassName := 'MyTrayIconClass';
hInstance := System.hInstance;
end;
RegisterClass(WC);
W := Windows.CreateWindow('MyTrayIconClass','MyVeryOwnTrayIconWindow',
ws_OverlappedWindow,0,0,0,0,0,0,hInstance,nil);
ShowWindow(W,sw_Hide);
UpdateWindow(W);
MainWindow := W;
End;
这个窗口使用普通的窗口函数创建。注意这个窗口的类型是“ws_OverlappedWindow”,但是这个尺寸是0,并且它是隐藏的,所有,它将不会显示出来。
下一步是加(注册)我们的图标。这将需要使用Shell_NotifyIcon这个API函数,这个函数实际上可以完成三个功能,这里只需要它的增加的特性。

Procedure AddTrayIcon;
Var IconData : TNotifyIconData;
Begin
With IconData do Begin
cbSize := SizeOf(IconData);
Wnd := MainWindow;
uID := 0;
uFlags := nif_Icon Or nif_Message Or nif_Tip;
uCallBackMessage := wm_MyCallBack;
hIcon := LoadIcon(hInstance,'MYICON');
StrCopy(szTip,PChar(TrayIconTip));
End;
Shell_NotifyIcon(nim_Add,@IconData);
End;
这个最重要的事情是TNotifyIconData的数据结构,它是一个设置Window句柄的数据结构,是一个记录参数,对我们来说,我们需要设置这个图标的窗口句柄(这将定义哪个窗口处理消息循环),回调消息号,图标,工具提示等。一旦这个数据设置了,我们就可以增加一个图标到任务栏上了。为了完成这个工作,使用nim_Add程序。
现行我们已经加了我们的图标到任务栏,下面需要决定如何处理消息。

Const
wm_MyCallback = wm_User+1000;
cm_Exit = 100; { we worry about... }
cm_About = 101; { ...these later }
这个实际的窗口处理过程也是相当普通。几个窗口消息(如wm_NCCreate)必须处理。然而,对我们来说,更重要的事情是处理wm_MyCallback和wm_Command消息:
Function WndProc(Window : hWnd; Msg,WParam,LParam : Integer): Integer; StdCall;
Begin
Result := 0;
Case Msg of
wm_NCCreate : Result := 1;
wm_Destroy : PostQuitMessage(0);
wm_Command : Begin { a command was chosen from the popup menu }
If (WParam = cm_Exit) Then
PostMessage(Window,wm_Destroy,0,0)
Else If (WParam = cm_About) Then
MessageBox(0,'Shell Test Copyright ?'+
'Jani J鋜vinen 1996.',
'About Shell Test',mb_OK)
Else OpenDesktopIcon(WParam-cm_About);
End;
wm_MyCallback : Begin { our icon was clicked }
If (LParam = wm_LButtonDown) Then
ShowIconPopupMenu
Else If (LParam = wm_RButtonDown) Then
ShowAboutPopupMenu;
End;
Else Result := DefWindowProc(Window,Msg,WParam,LParam);
End;
End;
就象你看到的一样,当用户单击图标时,Windows提示我们。注意我们不使用通常使用的wm_LButtonDown 消息,而使用wm_MyCallback message,详细的消息信息存储在LParam参数中。
当用户单击鼠标右键,我们创建一个菜单在桌面上。

Type
TIconData = Array[1..100] of String;
Var
IconData : TIconData;
Procedure ShowIconPopupMenu;
Var
ShellFolder : IShellFolder;
EnumIDList : IEnumIDList;
Result : hResult;
Dummy : ULong;
ItemIDList : TItemIDList;
Pntr : PItemIDList;
StrRet : TStrRet;
PopupMenu : hMenu;
ItemID : Integer;
Pos : TPoint;
Procedure AddToMenu(Item : String);
Var S : String;
Begin
IconData[ItemID-cm_About] := Item;
S := ExtractFileName(Item);
If (System.Pos('.',S) <> 0) Then SetLength(S,System.Pos('.',S)-1);
AppendMenu(PopupMenu,mf_Enabled Or mf_String,ItemID,PChar(S));
Inc(ItemID);
End;
begin
PopupMenu := CreatePopupMenu;
ItemID := cm_About+1;
SHGetDesktopFolder(ShellFolder);
ShellFolder.EnumObjects(MainWindow,SHCONTF_NONFOLDERS,EnumIDList);
Pntr := @ItemIDList;
Result := EnumIDList.Next(1,Pntr,Dummy);
While (Result = NoError) do Begin
ShellFolder.GetDisplayNameOf(Pntr,SHGDN_FORPARSING,@StrRet);
With StrRet do AddToMenu(String(CStr));
Result := EnumIDList.Next(1,Pntr,Dummy);
End;
EnumIDList.Release;
ShellFolder.Release;
GetCursorPos(Pos);
AppendMenu(PopupMenu,mf_Separator,0,'');
AppendMenu(PopupMenu,mf_Enabled Or mf_String,cm_Exit,'E&xit');
SetForegroundWindow(MainWindow);
TrackPopupMenu(PopupMenu,tpm_LeftAlign Or tpm_LeftButton,
Pos.X,Pos.Y,0,MainWindow,nil);
DestroyMenu(PopupMenu);
end;
上面的程序看起来有点复杂,你可以将它分成两个部分来看:创建和显示菜单。
列举创建菜单是用Windows的外壳接口完成的。首先,我们使用SHGetDesktopForlder函数得到使用桌面的IShellFolder接口。使用这个接口,我们能得到另一个接口的实例:IEnumIDList。这个接口通常实现实际的列举工作。我们简单的重复调用这个函数直到错误值返回(例如:所有的菜单被列举)。当我们得到一个菜单,我们使用AddToMenu函数加它。

当所有的菜单被列举和创建后,现在我们需要运行这个菜单。我们将找到的菜单保存到一个全局的List变量中,每一个菜单都拥有它的菜单号。这确保我们能得到它的索引。

OpenDesktopIcon(WParam-cm_About)

当然,WParam中储存了用户单击鼠标的菜单的菜单号(ID)。

下面我们将处理运行用户选择的菜单。

Procedure OpenDesktopIcon(Number : Integer);
Var
S : String;
I : Integer;
begin
S := IconData[Number];
I := ShellExecute(0,nil,PChar(S),nil,nil,sw_ShowNormal);
If (I < 32) Then Begin
S := 'Could not open selected item "'+S+'". '+
'Result was: '+IntToStr(I)+'.';
MessageBox(0,PChar(S),'Shell Test',mb_OK);
End;
end;
上面,Win 32 API函数ShellExecute做了所有的工作。

现在你应该能用Delphi创建简单的任务栏的程序了。

实际上,有一些免费的元件可以供您直接使用,不过,因为使用VCL,文件的大小将比较大,如果使用上面的方法,文件的大小将只要20K。当然,现在文件的大小已经不是我们该十分关注的问题了。
rosement 2000-03-13
  • 打赏
  • 举报
回复
我忘了告诉你,将CDlgApp::InitInstance()中的最后一句return FALSE;去掉!!!
Brierbird 2000-03-13
  • 打赏
  • 举报
回复
事情终于有了比较满意的结果了。
在此对各位的关心和帮助表示由衷的感谢。30分也有限本人可用分数又不同。如果哪位觉得分配不公或觉得自己应该得到更多的话,可要发信向我要在允许的条件下我可以给出一些。
分数并不是最重要的,相互帮助才是最可贵的。
再次感谢大家。
//bow

BTW:sodawater, 能把你的想法说具体一点吗?
haihong 2000-03-13
  • 打赏
  • 举报
回复
同意rosement的话,在CDlgApp::InitInstance()中的最后一句return TRUE。将Dialog关闭程序的时候加上CDlgApp::ExitInstance()
{
dlg->DestroyWindow();
delete dlg;
}
dlg 声明为全局
LJN 2000-03-12
  • 打赏
  • 举报
回复
那就用对象指针Create一个无模框, 最后别ShowWindows就行了.
Brierbird 2000-03-12
  • 打赏
  • 举报
回复
但是我是想让对话框处于运行,能不能有其它办法,我记得是有的,只是现在忘了。//sigh
Brierbird 2000-03-12
  • 打赏
  • 举报
回复
你说的在资源中去掉可视风格, 我试了一下, 也不行耶.
LJN 2000-03-12
  • 打赏
  • 举报
回复
修改CApp.cpp中的InitInstance函数, 去掉Dlg.DoModle(),
自建一个CWnd的子类, 把该CWnd对象赋给m_pMainWnd , 将进程控制起来.
再在想显示的时候DoModle就行了.
Brierbird 2000-03-12
  • 打赏
  • 举报
回复
但如果想在程序中实现应该是写哪个函数?
Hover 2000-03-12
  • 打赏
  • 举报
回复
在对话框的资源中去掉可视风格。
Brierbird 2000-03-12
  • 打赏
  • 举报
回复
Dlg都还没调用生成又如何ShowWindow(SW_HIDE)?
sodawater 2000-03-12
  • 打赏
  • 举报
回复
太简单了,在主程序中在调用DoModle之前用就行了
Brierbird 2000-03-12
  • 打赏
  • 举报
回复
(1)回iceberg: 你的想法很不错,可是我试过cs.style &= ~WS_VISIBLE也不管用。你是否成功过呢?
(2)回rosement:因为是基于对话框的程序,照你这么做,那么结果只能是程序一开始也就是结束了呀。
(3)回manne:你的“然后使它生成为任务栏类型的程序。(具体方法看相应书籍)。在其popup menu中添加show window选项去执行在前面去掉的一段即可”,能不能说得更清楚些,请恕小弟不才。
(4)回wzq: 是有模式对话框。即便在资源中设置为不可视也无济于事。你成功过吗?
Brierbird 2000-03-12
  • 打赏
  • 举报
回复
但关键是在什么时候用呀。
我的目的并不是在窗口显示出来后再Hide.
sodawater 2000-03-12
  • 打赏
  • 举报
回复
这个问题很简单,用ShowWindow这个函数中的这个SW_HIDE参数值就可以了
加载更多回复(4)

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧