markov
中階會員
 
 發表:55 回覆:135 積分:53 註冊:2003-12-01
發送簡訊給我
|
我自己寫了一個VCL,它是繼承TPanel,並利用TPanel的canvas畫圖.但是我遇到一個問題,那就是在程式一執行起來及修改TPanel的caption時,畫面會動作不正常,但是將程式縮小再放大畫面就會正常動作,我想請問一下這是什麼問題
|
pwipwi
版主
   
 發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
引言:
我自己寫了一個VCL,它是繼承TPanel,並利用TPanel的canvas畫圖.但是我遇到一個問題,那就是在程式一執行起來及修改TPanel的caption時,畫面會動作不正常,但是將程式縮小再放大畫面就會正常動作,我想請問一下這是什麼問題
markov你好:
修改Caption後,再呼叫Repaint可以正常顯示嗎?
|
markov
中階會員
 
 發表:55 回覆:135 積分:53 註冊:2003-12-01
發送簡訊給我
|
Repaint()及Invalidate()都試過了,沒有用
|
pwipwi
版主
   
 發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
可以請你詳述不正常的狀況嗎? 另外以這個情況看起來,有可能是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
發送簡訊給我
|
我嘗試在非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
發送簡訊給我
|
修改標題後,呼叫InvalidateRect(0,0,false);重畫。試試能否解決問題
|
markov
中階會員
 
 發表:55 回覆:135 積分:53 註冊:2003-12-01
發送簡訊給我
|
問題是有解決了,但是每次修改都會造成整個form在閃,有沒有辨法解決,再次謝謝你
|
liangnet
中階會員
 
 發表:19 回覆:148 積分:83 註冊:2004-01-03
發送簡訊給我
|
引言:
問題是有解決了,但是每次修改都會造成整個form在閃,有沒有辨法解決,再次謝謝你
試試看加入這一行後是否不會閃爍
>>
|
markov
中階會員
 
 發表:55 回覆:135 積分:53 註冊:2003-12-01
發送簡訊給我
|
|
pwipwi
版主
   
 發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
在改變標題後,加入下面的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
發送簡訊給我
|
在改變標題後,加入下面的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
發送簡訊給我
|
在改變標題後,加入下面的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
發送簡訊給我
|
改變Caption後,只要呼叫SetWindowPos函式就好。 我測式的結果是沒閃動的。
|
markov
中階會員
 
 發表:55 回覆:135 積分:53 註冊:2003-12-01
發送簡訊給我
|
雖然我查了老半天我還是查不出來為什麼你的不會閃我的還會,
但是真的很謝謝你,還幫我看程式
這一分不給你真的很對不起國家社會
不過我還是很納悶為什麼改變Caption之後,要呼叫SetWindowPos函式
|
pwipwi
版主
   
 發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
其實給分不給分不是重點啦 ![]()
因為這個主題很有趣~題外話 在透明視窗上,
如果改了內容,就要告訴所有被這個透明視窗蓋住的視窗要重畫,
但>> 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
發送簡訊給我
|
真是神奇有一封由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
發送簡訊給我
|
ControlStyle是一個Set類別,和元件屬性的有關係
那段程式碼是把csOpaque這個屬性拿掉。
(csOpaque->The control completely fills its client rectangle.) 還有那段見鬼的程式碼可能是我測試到一半不小心Post出來的… ![]()
雖然也可以作用,但是有
|
markov
中階會員
 
 發表:55 回覆:135 積分:53 註冊:2003-12-01
發送簡訊給我
|
你所謂的bug是什麼??
因為我run二個程式效果都一樣,
我所謂的閃是元件本身的閃
其他元件並不會閃,
看樣子SetWindowPos還是有發揮他的功效才是
|
pwipwi
版主
   
 發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
引言:
你所謂的bug是什麼??
因為我run二個程式效果都一樣,
我所謂的閃是元件本身的閃
其他元件並不會閃,
看樣子SetWindowPos還是有發揮他的功效才是
放上兩個元件…就會掛了。
所以我後來才會放棄那個方法
|
markov
中階會員
 
 發表:55 回覆:135 積分:53 註冊:2003-12-01
發送簡訊給我
|
|
pwipwi
版主
   
 發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
起因在處理OnPaint時,對父視窗呼叫了重畫的命令(為了有透明的底)。
這時為了防止自已在父視窗重畫時自已也被重畫,引進了一個成員變數NoPaint,擋下這個重畫的無窮廻圈。 但這樣只能解決單一個透明元件的重畫問題。二個以上就會互相呼叫,結果還是動不了…
|