線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2180
推到 Plurk!
推到 Facebook!

畫面重繪的問題

尚未結案
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-08-03 21:36:15 IP:61.229.xxx.xxx 未訂閱
我自己寫了一個VCL,它是繼承TPanel,並利用TPanel的canvas畫圖.但是我遇到一個問題,那就是在程式一執行起來及修改TPanel的caption時,畫面會動作不正常,但是將程式縮小再放大畫面就會正常動作,我想請問一下這是什麼問題
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-08-04 00:12:05 IP:211.76.xxx.xxx 未訂閱
引言: 我自己寫了一個VCL,它是繼承TPanel,並利用TPanel的canvas畫圖.但是我遇到一個問題,那就是在程式一執行起來及修改TPanel的caption時,畫面會動作不正常,但是將程式縮小再放大畫面就會正常動作,我想請問一下這是什麼問題
markov你好: 修改Caption後,再呼叫Repaint可以正常顯示嗎?
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-08-04 08:58:52 IP:211.21.xxx.xxx 未訂閱
Repaint()及Invalidate()都試過了,沒有用
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-08-04 14:28:21 IP:211.76.xxx.xxx 未訂閱
可以請你詳述不正常的狀況嗎?    另外以這個情況看起來,有可能是VCL裡面的資料(如Caption),沒有正確的update到TPanel的window的windowtext。也就是說,原因可能在於你是直接修改了property的處理方法,或者是繼承property的method後,沒有正確的處理該method應該做的事,造成資料的不同步。    以下面的vcl source code作例子  
 
procedure TListColumn.SetCaption(const Value: string);
begin
  if FCaption <> Value then
  begin
    FCaption := Value;
    DoChange;
  end;
end;
如果你繼承後,自已寫了一個SetCaption,就也要一樣呼叫DoChange。不然會有資料不同步的問題。 不過以上只是猜測,如果還是沒解決…再來細看你的Code…
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-08-04 15:09:00 IP:211.21.xxx.xxx 未訂閱
我嘗試在非VCL下做實驗,發現問題仍在 caption都能正常動作, 但問題是在於透明與否,一旦按下button1透明就會消失, 但是將視窗最小化再最大化後就會恢復透明 還請pwipwi大大抽空幫我看看,感激不盡     
//class的定義
class TTransPanel :public TPanel
{
  void __fastcall CreateParams(Controls::TCreateParams &Params)
  {
    TPanel::CreateParams(Params);
    Params.ExStyle  = WS_EX_TRANSPARENT;
  }
  void __fastcall AdjustColors(TPanelBevel Bevel,TColor& TopColor,TColor& BottomColor)
  {
    TopColor = clBtnHighlight;
    if (Bevel == bvLowered) TopColor = clBtnShadow;
    BottomColor = clBtnShadow;
    if (Bevel == bvLowered) BottomColor = clBtnHighlight;
  }
  void __fastcall Paint()
  {
    DynamicArray Alignments;
    Alignments.set_length(3);
    Alignments[taLeftJustify] = DT_LEFT;
    Alignments[taCenter] = DT_CENTER;
    Alignments[taRightJustify] = DT_RIGHT;
    TRect Rect;
    TColor TopColor, BottomColor;
    int FontHeight;
    Longint Flags;
    Rect = GetClientRect();
    if (BevelOuter != bvNone)
    {
      AdjustColors(BevelOuter,TopColor, BottomColor);
      Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
    }
    Frame3D(Canvas, Rect, Color, Color, BorderWidth);
    if (BevelInner != bvNone)
    {
      AdjustColors(BevelInner,TopColor, BottomColor);
      Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
    }
    Canvas->Brush->Color = Color;
    //Canvas->FillRect(Rect); //註解掉這一句,就透明了。下面的bsClear保??Caption的不使用底色。
    Canvas->Brush->Style = bsClear;
    Canvas->Font = this->Font;
    FontHeight = Canvas->TextHeight('W');        Rect.Top = ((Rect.Bottom   Rect.Top) - FontHeight) / 2;
    Rect.Bottom = Rect.Top   FontHeight;
    Flags = DT_EXPANDTABS | DT_VCENTER | Alignments[Alignment];
    Flags = DrawTextBiDiModeFlags(Flags);
    DrawText(Canvas->Handle, Caption.c_str(), -1, &Rect, Flags);      }
public:
  __fastcall virtual TTransPanel(TComponent* AOwner):TPanel(AOwner)
  {
    ControlStyle >> csOpaque;
    Width  = 185;
    Height = 41;
  }
};
 
//呼叫class的動作
void __fastcall TForm1::FormCreate(TObject *Sender)
{
         TransPanel1=new TTransPanel(Application);
         TransPanel1->Parent=Form1;
         TransPanel1->Font->Color=clRed;
         TransPanel1->Caption="123";
         TransPanel1->BevelInner=bvNone;
         TransPanel1->BevelOuter=bvNone;
         TransPanel1->Visible=true;
         TransPanel1->Height=100;
         TransPanel1->Width=100;
}    void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
        delete TransPanel1;
}    void __fastcall TForm1::Button1Click(TObject *Sender)
{
         TransPanel1->Caption="124";
}
 
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-08-05 03:01:47 IP:211.76.xxx.xxx 未訂閱
修改標題後,呼叫InvalidateRect(0,0,false);重畫。試試能否解決問題
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-08-05 09:19:18 IP:211.21.xxx.xxx 未訂閱
問題是有解決了,但是每次修改都會造成整個form在閃,有沒有辨法解決,再次謝謝你
liangnet
中階會員


發表:19
回覆:148
積分:83
註冊:2004-01-03

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-08-05 09:49:37 IP:218.170.xxx.xxx 未訂閱
引言: 問題是有解決了,但是每次修改都會造成整個form在閃,有沒有辨法解決,再次謝謝你
試試看加入這一行後是否不會閃爍 >>
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-08-05 09:57:31 IP:211.21.xxx.xxx 未訂閱
我試過了,透明會消失,而且還是會閃
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-08-05 10:36:34 IP:211.76.xxx.xxx 未訂閱
在改變標題後,加入下面的Code。 SetWindowPos(Form1->Handle,0,0,0,0,0,SWP_NOCOPYBITS |SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); 發表人 - pwipwi 於 2004/08/05 11:01:28
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-08-05 10:59:51 IP:211.76.xxx.xxx 未訂閱
在改變標題後,加入下面的Code。
 
    SetWindowPos(Form1->Handle,0,0,0,0,0,SWP_NOCOPYBITS
    |SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); 
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-08-05 14:11:56 IP:211.21.xxx.xxx 未訂閱
在改變標題後,加入下面的Code。        SetWindowPos(Form1->Handle,0,0,0,0,0,SWP_NOCOPYBITS     |SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);         並沒有太太的影響, 不過加入Repaint旗標之後好很多了,雖然元件本身還是會閃 我一度懷疑是Parent->Repaint(); 因為都是先show TPanel的造型, 再清掉畫現在這個元件的造型 但是如果我把Parent->Repaint();這一行清掉又會連現在的元件都不畫了 雖然我不知道為什麼
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-08-05 14:42:29 IP:211.76.xxx.xxx 未訂閱
改變Caption後,只要呼叫SetWindowPos函式就好。 我測式的結果是沒閃動的。
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-08-06 11:54:46 IP:211.21.xxx.xxx 未訂閱
雖然我查了老半天我還是查不出來為什麼你的不會閃我的還會, 但是真的很謝謝你,還幫我看程式 這一分不給你真的很對不起國家社會 不過我還是很納悶為什麼改變Caption之後,要呼叫SetWindowPos函式
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-08-06 12:58:10 IP:211.76.xxx.xxx 未訂閱
其實給分不給分不是重點啦 因為這個主題很有趣~題外話 在透明視窗上, 如果改了內容,就要告訴所有被這個透明視窗蓋住的視窗要重畫, 但>> class="code"> //class的定義 class TTransPanel :public TPanel { void __fastcall CreateParams(Controls::TCreateParams &Params) { TPanel::CreateParams(Params); Params.ExStyle = WS_EX_TRANSPARENT; } void __fastcall AdjustColors(TPanelBevel Bevel,TColor& TopColor,TColor& BottomColor) { TopColor = clBtnHighlight; if (Bevel == bvLowered) TopColor = clBtnShadow; BottomColor = clBtnShadow; if (Bevel == bvLowered) BottomColor = clBtnHighlight; } void __fastcall Paint() { DynamicArray Alignments; Alignments.set_length(3); Alignments[taLeftJustify] = DT_LEFT; Alignments[taCenter] = DT_CENTER; Alignments[taRightJustify] = DT_RIGHT; TRect Rect; TColor TopColor, BottomColor; int FontHeight; Longint Flags; Rect = GetClientRect(); if (BevelOuter != bvNone) { AdjustColors(BevelOuter,TopColor, BottomColor); Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); } Frame3D(Canvas, Rect, Color, Color, BorderWidth); if (BevelInner != bvNone) { AdjustColors(BevelInner,TopColor, BottomColor); Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); } Canvas->Brush->Color = Color; //Canvas->FillRect(Rect); //註解掉這一句,就透明了。下面的bsClear保??Caption的不使用底色。 Canvas->Brush->Style = bsClear; Canvas->Font = this->Font; FontHeight = Canvas->TextHeight('W'); Rect.Top = ((Rect.Bottom Rect.Top) - FontHeight) / 2; Rect.Bottom = Rect.Top FontHeight; Flags = DT_EXPANDTABS | DT_VCENTER | Alignments[Alignment]; Flags = DrawTextBiDiModeFlags(Flags); DrawText(Canvas->Handle, Caption.c_str(), -1, &Rect, Flags); } public: __fastcall virtual TTransPanel(TComponent* AOwner):TPanel(AOwner) { ControlStyle >> csOpaque; Width = 185; Height = 41; } }; TTransPanel* TransPanel1; //呼叫class的動作 void __fastcall TForm1::FormCreate(TObject *Sender) { TransPanel1=new TTransPanel(Application); TransPanel1->Parent=Form1; TransPanel1->Font->Color=clRed; TransPanel1->Caption="123"; TransPanel1->BevelInner=bvNone; TransPanel1->BevelOuter=bvNone; TransPanel1->Visible=true; TransPanel1->Height=200; TransPanel1->Width=200; } void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose) { delete TransPanel1; } void __fastcall TForm1::Button1Click(TObject *Sender) { TransPanel1->Caption = "123123"; SetWindowPos(Form1->Handle,0,0,0,0,0,SWP_NOCOPYBITS |SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } //---------------------------------------------------------------------------
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#16 引用回覆 回覆 發表時間:2004-08-06 14:35:39 IP:211.21.xxx.xxx 未訂閱
真是神奇有一封由ktop寄給我的你的回覆, 你還有附上你修改過後的source code, 可以在ktop上卻沒有, 我一直只是ktop的bug 沒有想到你剛剛附上來的source code居然也不是你寄給我的source code 見鬼了 下列是你當初給我的程式,我再稍做修改的完整程式碼 < class="code"> class TTransPanel :public TPanel { bool NoRepaint; void __fastcall CreateParams(Controls::TCreateParams &Params) { TPanel::CreateParams(Params); Params.ExStyle = WS_EX_TRANSPARENT; } void __fastcall AdjustColors(TPanelBevel Bevel,TColor& TopColor,TColor& BottomColor) { TopColor = clBtnHighlight; if (Bevel == bvLowered) TopColor = clBtnShadow; BottomColor = clBtnShadow; if (Bevel == bvLowered) BottomColor = clBtnHighlight; } void __fastcall Paint() { if(NoRepaint) { NoRepaint = false; return; } NoRepaint = true; SetWindowPos(Parent->Handle,0,0,0,0,0,SWP_NOCOPYBITS |SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); Parent->Repaint(); DynamicArray Alignments; Alignments.set_length(3); Alignments[taLeftJustify] = DT_LEFT; Alignments[taCenter] = DT_CENTER; Alignments[taRightJustify] = DT_RIGHT; TRect Rect; TColor TopColor, BottomColor; int FontHeight; Longint Flags; Rect = GetClientRect(); if (BevelOuter != bvNone) { AdjustColors(BevelOuter,TopColor, BottomColor); Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); } Frame3D(Canvas, Rect, Color, Color, BorderWidth); if (BevelInner != bvNone) { AdjustColors(BevelInner,TopColor, BottomColor); Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth); } Canvas->Brush->Color = Color; //Canvas->FillRect(Rect); Canvas->Brush->Style = bsClear; Canvas->Font = this->Font; FontHeight = Canvas->TextHeight('W'); Rect.Top = ((Rect.Bottom Rect.Top) - FontHeight) / 2; Rect.Bottom = Rect.Top FontHeight; Flags = DT_EXPANDTABS | DT_VCENTER | Alignments[Alignment]; Flags = DrawTextBiDiModeFlags(Flags); DrawText(Canvas->Handle, Caption.c_str(), -1, &Rect, Flags); } public: __fastcall virtual TTransPanel(TComponent* AOwner):TPanel(AOwner) { ControlStyle >> csOpaque; Width = 185; Height = 41; NoRepaint = false; } }; 由於該段程式碼是網路上抓來的, 我想順便請教一下, CreateParams及ControlStyle >> csOpaque; 這二行是什麼意思?
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#17 引用回覆 回覆 發表時間:2004-08-06 15:18:14 IP:211.76.xxx.xxx 未訂閱
ControlStyle是一個Set類別,和元件屬性的有關係 那段程式碼是把csOpaque這個屬性拿掉。 (csOpaque->The control completely fills its client rectangle.)    還有那段見鬼的程式碼可能是我測試到一半不小心Post出來的… 雖然也可以作用,但是有
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#18 引用回覆 回覆 發表時間:2004-08-07 15:59:02 IP:220.139.xxx.xxx 未訂閱
你所謂的bug是什麼?? 因為我run二個程式效果都一樣, 我所謂的閃是元件本身的閃 其他元件並不會閃, 看樣子SetWindowPos還是有發揮他的功效才是
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#19 引用回覆 回覆 發表時間:2004-08-07 19:19:21 IP:211.76.xxx.xxx 未訂閱
引言: 你所謂的bug是什麼?? 因為我run二個程式效果都一樣, 我所謂的閃是元件本身的閃 其他元件並不會閃, 看樣子SetWindowPos還是有發揮他的功效才是
放上兩個元件…就會掛了。 所以我後來才會放棄那個方法
markov
中階會員


發表:55
回覆:135
積分:53
註冊:2003-12-01

發送簡訊給我
#20 引用回覆 回覆 發表時間:2004-08-09 09:29:22 IP:211.21.xxx.xxx 未訂閱
真的掛了,可是為什麼呢?
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#21 引用回覆 回覆 發表時間:2004-08-09 22:13:41 IP:211.76.xxx.xxx 未訂閱
起因在處理OnPaint時,對父視窗呼叫了重畫的命令(為了有透明的底)。 這時為了防止自已在父視窗重畫時自已也被重畫,引進了一個成員變數NoPaint,擋下這個重畫的無窮廻圈。    但這樣只能解決單一個透明元件的重畫問題。二個以上就會互相呼叫,結果還是動不了…
系統時間:2024-11-26 1:26:48
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!