用showwindow函数显示窗体,不能显示按钮,且无法关闭,为什么???(200分)

  • 主题发起人 主题发起人 ZHC
  • 开始时间 开始时间
有意思,呵,我等会儿试试看。
 
有意思,呵,我等会儿试试看。
 
我把那边的问题搞定了,可是这个问题还得想办法!<br>&lt;a href="DispQ.asp?LID=386017"&gt;二次运行的问题?&lt;/a&gt;
 
希望有人能够从delphi的源码的深度,分析产生问题的原因,如果实在<br>不行,我只能用lml的递归显示所有controls的方法了,毕竟有方法<br>总比束手无策要好。<br>另外我还有两个问题:<br>1:lml的解决方法中,有一条是在form2的OnActivate事件中调用<br>form.show,但是在实际使用中发现,只用form2第一次显示时<br>系统才调用该事件, &nbsp; 以后我关闭了该窗口(但并不释放它),再重新显示它时,<br>系统就不再调用该事件了,这是为什么。<br>2:在我的程序中,form2的formstyle属性设为fsStayOnTop,程序运行时<br>根据需要,form2不断地hide,然后再重新show,运行一段时间以后<br>form2就会显示到其他窗口的后面去,好像fsStayOnTop这个属性<br>不翼而飞了,我只有在调用form2.show之前先调用<br>SetWindowPos(form2.handle,HWND_TOPMOST,0,0,0,0,swp_nomove or swp_nosize);<br>才能解决问题,这是为什么,难道fsStayOnTop属性真的会不翼而飞么?<br>我的系统是delphi3.0+Ewin95OS2<br><br>BTW,为了发出以上文字,我花了一个小时时间,光联上大富翁就花了30分钟时间,<br>结果写了一半时系统又崩溃了,重新启动机子,重新上网,重新写,真是气人。<br>强烈要求,提高大富翁的响应速度。
 
我也不希望我的答案被接受,分数是次要的,关键是找到问题的真正答案和<br>学到一点真的东西--比如BaKuBaKu兄分析二次调用问题的过程,但是那个结<br>果仅仅能的给这个问题一点启发,因为目前面对的不再是一个Application,<br>而是一个窗口。<br>希望BaKuBaKu再接再厉,如果真能解决,我也愿意出100分奖励啊--为了这<br>两个问题!
 
说来好笑!这样就可以了。不论嵌套多少层控件。<br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE);<br>&nbsp; Form2.Visible := True;<br>end;<br>
 
这个问题的确需要从源码级解答。<br>TControl 有一个私有的 SetVisible 方法和 Visible 属性。<br>private<br>&nbsp; FVisible: Boolean;<br>&nbsp; procedure SetVisible(Value: Boolean);<br>public // 公共属性<br>&nbsp; property Visible: Boolean read FVisible write SetVisible stored IsVisibleStored default True;<br>&nbsp; ...<br>end;<br>procedure TControl.SetVisible(Value: Boolean);<br>begin<br>&nbsp; if FVisible &lt;&gt; Value then<br>&nbsp; begin<br>&nbsp; &nbsp; VisibleChanging; // TCustomForm 重载该方法,防止改变 MDI Child 的 Visible,但是与本题无关<br>&nbsp; &nbsp; FVisible := Value;<br>&nbsp; &nbsp; Perform(CM_VISIBLECHANGED, Ord(Value), 0); // 关键是这句话<br>&nbsp; &nbsp; RequestAlign;<br>&nbsp; end;<br>end;<br><br>但是 TCustomForm 又重写了 SetVisible 方法和 Visible 属性,注意是重写不是重载:<br>private<br>&nbsp; procedure SetVisible(Value: Boolean);<br>protected // 保护属性<br>&nbsp; property Visible write SetVisible default False;<br>&nbsp; ...<br>end;<br>procedure TCustomForm.SetVisible(Value: Boolean);<br>begin<br>&nbsp; if fsCreating in FFormState then<br>&nbsp; &nbsp; if Value then<br>&nbsp; &nbsp; &nbsp; Include(FFormState, fsVisible) else<br>&nbsp; &nbsp; &nbsp; Exclude(FFormState, fsVisible)<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; if Value and (Visible &lt;&gt; Value) then SetWindowToMonitor;<br>&nbsp; &nbsp; inherited Visible := Value; // 我们只关心这句话<br>&nbsp; end;<br>end;<br><br>&nbsp; 象这样的写法我还是第一次看见,不是重载虚函数,而是重写,不知道 Object Pascal 的<br>语法为什么允许这样的写法。但是先不管它。<br><br>&nbsp; 我们设置 Form.Visible ,其实首先调用的是 TCustomForm.SetVisible ,在这里,<br>&nbsp; &nbsp; inherited Visible := Value;<br>产生对 TControl.SetVisible 的调用,然后 Perform(CM_VISIBLECHANGED, Ord(Value), 0);<br>发出 CM_VISIBLECHANGED 消息,但是这个消息不是被 TControl.CMVisibleChanged 方法得到,<br>&nbsp; procedure CMVisibleChanged(var Message: TMessage); message CM_VISIBLECHANGED;<br>因为 TWinControl 截获了它,<br>procedure TWinControl.CMVisibleChanged(var Message: TMessage);<br>begin<br>&nbsp; if not FVisible and (Parent &lt;&gt; nil) then RemoveFocus(False);<br>&nbsp; if not (csDesigning in ComponentState) or<br>&nbsp; &nbsp; (csNoDesignVisible in ControlStyle) then &lt;font color = #ff0000&gt;&lt;strong&gt;UpdateControlState&lt;/font&gt;&lt;/strong&gt;; // 这里产生了对子控件的遍历刷新<br>end;<br><br>procedure TWinControl.UpdateControlState;<br>var<br>&nbsp; Control: TWinControl;<br>begin<br>&nbsp; Control := Self;<br>&nbsp; while Control.Parent &lt;&gt; nil do<br>&nbsp; begin<br>&nbsp; &nbsp; Control := Control.Parent;<br>&nbsp; &nbsp; if not Control.Showing then Exit;<br>&nbsp; end;<br>&nbsp; // 上面的代码是找到本控件的最上级父亲,赋给 Control 变量<br>&nbsp; if (Control is TCustomForm) or (Control.FParentWindow &lt;&gt; 0) then &lt;font color = #ff0000&gt;&lt;strong&gt;UpdateShowing&lt;/font&gt;&lt;/strong&gt;; ;<br>end;<br><br>procedure TWinControl.UpdateShowing;<br>var<br>&nbsp; ShowControl: Boolean;<br>&nbsp; I: Integer;<br>begin<br>&nbsp; ShowControl := (FVisible or (csDesigning in ComponentState) and<br>&nbsp; &nbsp; not (csNoDesignVisible in ControlStyle)) and<br>&nbsp; &nbsp; not (csReadingState in ControlState);<br>&nbsp; if ShowControl then // 如果需要显示<br>&nbsp; begin<br>&nbsp; &nbsp; if FHandle = 0 then CreateHandle;<br>&nbsp; &nbsp; if FWinControls &lt;&gt; nil then<br>&nbsp; &nbsp; &nbsp; for I := 0 to FWinControls.Count - 1 do // 遍历控件的所有直接儿子并刷新,注意这里类似递归,其实不是递归<br>&nbsp; &nbsp; &nbsp; &nbsp; TWinControl(FWinControls).&lt;font color = #ff0000&gt;&lt;strong&gt;UpdateShowing&lt;/font&gt;&lt;/strong&gt;;<br>&nbsp; end;<br>&nbsp; if FHandle &lt;&gt; 0 then<br>&nbsp; &nbsp; if FShowing &lt;&gt; ShowControl then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; FShowing := ShowControl;<br>&nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; Perform(CM_SHOWINGCHANGED, 0, 0); // 通过发送 CM_SHOWINGCHANGED 消息刷新控件<br>&nbsp; &nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; &nbsp; FShowing := not ShowControl;<br>&nbsp; &nbsp; &nbsp; &nbsp; raise;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>end;<br><br>procedure TWinControl.CMShowingChanged(var Message: TMessage);<br>const<br>&nbsp; ShowFlags: array[Boolean] of Word = (<br>&nbsp; &nbsp; SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_HIDEWINDOW,<br>&nbsp; &nbsp; SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_SHOWWINDOW);<br>begin<br>&nbsp; SetWindowPos(FHandle, 0, 0, 0, 0, 0, ShowFlags[FShowing]); // 真正显示各个控件<br>end;<br><br>&nbsp; 由于在处理 CM_VISIBLECHANGED 消息的时候需要判断 FVisible ,如果 FVisible = False<br>将不会继续处理,但是 FVisible 是 TControl 的私有变量,我想了一下,也没有别的方法<br>直接存取 FVisible ,所以提出了上面的办法,仍然通过 Visible 属性去设置它,好处就是<br>不会闪烁。
 
ZHC 大侠的精神令我非常感动。<br>&nbsp; 我现在在教育网,速度比较快,而且不花钱,因此能经常来看一看,如果上网条件象 ZHC 大侠一样,<br>我有点怀疑我能否坚持下来。所以我觉得我的劳动是值得的,同别人分享知识是一件很快乐的事情,<br>希望下次能再有机会和各位朋友讨论问题。<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; From: BaKuBaKu
 
我觉的 form 没有击活它上面的控件也就只是 show 了出来。也没有击活<br>如果每个按纽都击活了,哪还不如 form.active
 
非常感谢有这么多朋友来回答我的问题,最近一段时间我对我的电脑进行了升级,<br>所以很长时间没有登陆大富翁,在这里表示歉意。
 

Similar threads

后退
顶部