怎样让用API创建的窗口不被最小化? ( 积分: 100 )

  • 主题发起人 apacheii
  • 开始时间
RPWT?呵呵,我怎么可以。<br> <br> begin<br> &nbsp;case uMsg of<br> &nbsp; WM_SYSCOMMAND:<br> &nbsp; &nbsp;if wParam=SC_MINIMIZE then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShowWindow(hwnd,SW_RESTORE);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result:=0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp; &nbsp; &nbsp;end; &nbsp; <br> &nbsp; &nbsp;WM_SIZE:<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; if wParam = SIZE_MINIMIZED then<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; showwindow(hwnd,sw_normal);<br> &nbsp; &nbsp; &nbsp; result:=0;<br> &nbsp; &nbsp; &nbsp; exit;<br> &nbsp; &nbsp; end;<br> &nbsp; &nbsp;end; &nbsp;<br> &nbsp;end;<br> &nbsp;Result:=0;
 
to 江南草:<br> &nbsp;谢谢你的回复,不过你给我的方法我早已经试过了,这样做只能是在窗口被最小化后马上又恢复了原状,中间过程就会出现最小化和还原的动画。实际上这样做根本没有把消息给拦截掉,只是在消息之后做了一些事而已。。。。。。<br><br> &nbsp;Delphi的TApplication会接管程序中窗口的消息,把TApplication对象本身的窗口设置为工具拦窗口,并把它最小化,隐藏掉,程序的主窗口就无法直接最小化了,不管是从任务管理器里,还是用SPY给它发消息。请研究过Forms.pas中TApplication对象的高手出来讲讲其中的道理好吗?<br><br> &nbsp;我说过,这个问题大家如嫌分不够的话,我可以再加,不管多少,只要能让我们明白其中道理。
 
还有,PeekMessage函数怎样才能从消息队列中删除特定的消息?我试过用GetMessage,它会把所有消息都给删掉,窗口无法正常显示和操作了!
 
查了下,问题是dialog的窗口函数。<br>其实用dialog并不方便控制,但既然用了DialogBox/CreateDialog,则WindowFunction的返回值应该是boolean类型。<br>dialog的消息流程有些不同,首先是parent窗口调用DefDlgProc,这个proc再call我们定义的DlgFunction,具体到每个消息,若有处理,则返回true,若未处理,返回false.<br><br>function MainProc(hDlg: hWnd; DlgMsg: UINT; wParam: WPARAM;<br> &nbsp;lParam: LPARAM):bool; stdcall;<br>var<br> &nbsp;Msg:TMsg;<br>begin<br> &nbsp;case DlgMsg of<br> &nbsp; &nbsp;WM_SYSCOMMAND:<br> &nbsp; &nbsp;case LOWORD(wParam) of<br> &nbsp; &nbsp; &nbsp;SC_MINIMIZE:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;result:=true; &nbsp;//若为false则被最小化<br> &nbsp; &nbsp; &nbsp; &nbsp;exit;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br> &nbsp;Result := false;<br>end;
 
to 江南草:<br>正如你所说,DlgFunction确实应该是boolean型!我改过来后能正常拦截到消息了,不过我在测试的时候窗口又被最小化了。。。。看来剩下的问题就是拦截的消息有问题,我用SPY++跟踪了下,当最小化时被跟踪到的消息我都试过了,结果还是不行!
 
不知道楼主的问题解决了没,我的做法是这样的,没有直接用CreateWindowEx,在D中创建两个窗体Form1,Form2,Form1上放一个Button1,代码如下<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> &nbsp;SendMessage(Form2.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);<br>end;<br><br>TForm2中重载WndProc方法:<br>procedure TForm2.WndProc(var Message: TMessage);<br>begin<br> &nbsp;case Message.Msg of<br> &nbsp;WM_SYSCOMMAND:<br> &nbsp; &nbsp;if Message.WParamLo = SC_MINIMIZE then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Message.Result := 1;<br> &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br><br> &nbsp;inherited;<br><br>end;<br><br>这样子FORM2就不能被最小化了!
 
to lzh7735:<br>谢谢你的回复,不过我本来没打算用VCL来写这个程序,如果用了VCL,我这个问题也就不会产生了。。。。。。<br>现在我只想知道的是,我的对话框窗口(是程序的主窗口)应该拦截掉什么消息才不会被别的程序和操作系统最小化。
 
试试收到WM_SYSCOMMAND的SC_MINIMIZE消息后把LParam改成SC_RESTORE然后再调用DefWindowProc.
 
直接建立窗口版:<br><br>// ------- HelloWin.dpr -------<br><br>program HelloWin;<br><br>uses Windows, Messages;<br><br>function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;<br>begin<br> &nbsp;case Msg of<br> &nbsp; &nbsp;WM_SYSCOMMAND:<br> &nbsp; &nbsp; &nbsp;if (wParam &lt;&gt; SC_MINIMIZE) then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := DefWindowProc(hWnd, Msg, wParam, lParam)<br> &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := 0; // 不作处理<br><br> &nbsp; &nbsp;WM_DESTROY:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;PostQuitMessage(0);<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := 0;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;else Result := DefWindowProc(hWnd, Msg, wParam, lParam);<br> &nbsp;end;<br>end;<br><br>const<br> &nbsp;AppName = 'HelloWin';<br><br>var<br> &nbsp;Msg: TMsg;<br> &nbsp;WndClass: TWndClass;<br><br>begin<br> &nbsp;WndClass.style := CS_HREDRAW or CS_VREDRAW;<br> &nbsp;WndClass.lpfnWndProc := @WndProc;<br> &nbsp;WndClass.cbClsExtra := 0;<br> &nbsp;WndClass.cbWndExtra := 0;<br> &nbsp;WndClass.hInstance := HInstance;<br> &nbsp;WndClass.hIcon := LoadIcon(0, IDI_APPLICATION);<br> &nbsp;WndClass.hCursor := LoadCursor(0, IDC_ARROW);<br> &nbsp;WndClass.hbrBackground := GetStockObject(BLACK_BRUSH);<br> &nbsp;WndClass.lpszMenuName := nil;<br> &nbsp;WndClass.lpszClassName := AppName;<br> &nbsp;RegisterClass(WndClass);<br><br> &nbsp;CreateWindow(AppName, 'The Hello Program',<br> &nbsp; &nbsp;WS_OVERLAPPEDWINDOW or WS_VISIBLE,<br> &nbsp; &nbsp;Integer(CW_USEDEFAULT), SW_SHOW,<br> &nbsp; &nbsp;Integer(CW_USEDEFAULT), 0,<br> &nbsp; &nbsp;0, 0, HInstance, nil);<br><br> &nbsp;while GetMessage(Msg, 0, 0, 0) do<br> &nbsp;begin<br> &nbsp; &nbsp;TranslateMessage(Msg);<br> &nbsp; &nbsp;DispatchMessage(Msg);<br> &nbsp;end;<br>end.
 
资源对话框版:<br><br>// ------- HelloDlg.rc -------<br><br> 66 DIALOG DISCARDABLE 0x8000, 0x8000, 0x8000, 0x8000<br> &nbsp; STYLE WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU<br> &nbsp; CAPTION &quot;HelloDlg&quot;<br> &nbsp; FONT 8, &quot;MS Sans Serif&quot;<br> BEGIN<br> END<br><br><br>// ------- HelloDlg.dpr -------<br><br>program HelloDlg;<br><br>{$R 'HelloDlg.res' 'HelloDlg.rc'}<br><br>uses Windows, Messages;<br><br>function DlgProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;<br>begin<br> &nbsp;case (uMsg) of<br> &nbsp; &nbsp;WM_COMMAND:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (LOWORD(wParam) = IDCANCEL) then EndDialog(hWnd, 0);<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := FALSE;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;WM_SYSCOMMAND:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := (wParam = SC_MINIMIZE);<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;else Result := FALSE; // 要求DefDlgProc()处理<br> &nbsp;end;<br>end;<br><br>begin<br> &nbsp;DialogBox(HInstance, MakeIntResource(66), 0, @DlgProc);<br>end.
 
判断消息是否其他线程发来的, 用InSendMessage(), :)
 
谢谢麻子兄,你给的代码我也试过了,拦截WM_SYSCOMMAND消息不起作用,只能让窗口在点系统菜单和系统按扭的时候不为所动。判断InSendMessage后再处理也是一样。。。。。。看来这个程序要想不让别的程序最小化确实有点难了。。。。。。<br>麻子兄,请再帮忙想想办法吧
 
什么叫不起作用, 我都测试过了, 哪里有问题? 你如何测试的?
 
是真的啊,麻子兄。。。。。。[:(]<br>用Windows 任务管理器,在应用程序页里选中我的程序,点右键菜单里的“最小化”可以使窗口最小化,还有用SPY工具也可以最小化这个窗口。。。。。。<br>最主要的是不光是这些程序可以最小化我的程序,连那个“美萍安全卫士”在锁定界面里也可以最小化我这个程序。因为我的程序是用来自动运行任务的,为了让用户知道这个程序正在工作,一定要显示出窗口(整个程序只有一个对话框),而不能最小化,所以才提出了这个问题。之前我自己试过很多方法,都没效果,虽然用鼠标去点最小化按扭不起作用了。。。。。。但并没有真正做到不能最小化。用VCL确实可以做到,不过我不想用VCL来写这个程序,一是为了能巩固一下Win32编程知识,二是我觉得没必要用VCL。<br>这个问题问到这个份上了,也许麻子兄都觉得我太婆婆妈妈了吧?请别生气,大家。。。。。。
 
用VCL确实可以做到? 具体怎么作的? 可以说说吗?
 
如果去除WS_MINIMIZEBOX风格,则最小化按钮不可用,您说的不是这个方法吧?<br> &nbsp;CreateWindow(AppName, AppName,<br> &nbsp; &nbsp;WS_OVERLAPPEDWINDOW xor WS_MINIMIZEBOX or WS_VISIBLE,<br> &nbsp; &nbsp;Integer(CW_USEDEFAULT), SW_SHOW,<br> &nbsp; &nbsp;Integer(CW_USEDEFAULT), 0,<br> &nbsp; &nbsp;0, 0, HInstance, nil);
 
不是办法的办法:<br> &nbsp; &nbsp;WM_SIZE:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (wParam = SIZE_MINIMIZED) then ShowWindow(hWnd, SW_RESTORE);<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := 0;<br> &nbsp; &nbsp; &nbsp;end;
 
唉。。。。。。<br>用VCL的话,主窗体创建后把Application的窗口设置成toolwindow,再把它最小化掉,主窗口就无法最小化了,用spy和任务管理器向主窗口发送最小化消息也没反映了~<br> &nbsp; &nbsp;WM_SIZE:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (wParam = SIZE_MINIMIZED) then ShowWindow(hWnd, SW_RESTORE);<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := 0;<br> &nbsp; &nbsp; &nbsp;end;<br>这个办法根本没用啊,程序一运行就不断的最小,还原,又最小,还原。。。。。。<br>我想如果能自己定义DefWindowProc应该有办法了吧。<br>如果有人能真正解决这个问题,我把我所有的分送给他了。目前有2248分。
 
我发现提出问题时最多只能放300分上去,请不要担心,我可以多分几次发分。
 
截获最小化如何?
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
537
import
I
I
回复
0
查看
560
import
I
顶部