Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Vykreslovaní obrazku ve StringGridu

Zdravím.
Muže mi někdo vysvětlit toto.
Vložím do ID buňky ve StringGridu obrázek, který je v image.picture

StringGrid1.Canvas.StretchDraw(StringGrid1.CellRec t(0,1),Image1.Picture.Graphic);

Ve Windows 7 je vše OK.
Když ho však spustím ve Windows XP a přejedu přes ten obrázek , nějakým jiným programem, (třeba kalkulačkou ),obrazek zmizne.

Dal jsem to vykreslovat do události "OnPaint" a je to skoro to same.

Předmět Autor Datum
Mel bys vykreslovat v OnDrawCell, pripadne v OnAdvancedDrawCell
Jan Fiala 31.10.2011 10:13
Jan Fiala
Tak jsem vyzkoušel ten DrawCell a spíš než úspěch se do toho začínám záplatovat. Funguje to, ale spí…
Mirek Mastny 01.11.2011 07:08
Mirek Mastny
Pokud jsem to dobře pochopil tak procedura DrawCell běží furt dokola nezávisle na programu a furt do…
pme 01.11.2011 10:25
pme
Pochopil jsi to spatne. Bud StringGrid uzivatelsky vykreslujes nebo ne. Pokud vykreslujes, musis vyk…
Jan Fiala 01.11.2011 11:10
Jan Fiala
Tak toto ale vubec nechapu. Jak na barevny text ve sloupci neno barevne bunky vim. Přikladu je na ne…
Mirek Mastny 01.11.2011 13:29
Mirek Mastny
Jednoduchšie riešenie? www.nirsoft.net. Načo vymýšľať vymyslené...
pme 01.11.2011 13:40
pme
OnDrawCell ti vraci primo rect pro vykreslovani a bunku, kterou vykreslujes. Pises, ze texty vykresl…
Jan Fiala 01.11.2011 14:31
Jan Fiala
Děkují moc za pomoc. Pokud to bylo z hlavy tak jste se docela trefil. Problém byl jen tady ImageList…
Mirek Mastny 02.11.2011 06:54
Mirek Mastny
Neni to pravda. Podporuje pruhledne pozadi. Pri pradavani do ImageList urcujes masku. Co se tyka pr…
Jan Fiala 02.11.2011 09:44
Jan Fiala
Funguje.Děkuji moc.
Mirek Mastny 03.11.2011 06:12
Mirek Mastny
Moh byh ještě jeden dotaz ohledně StringGridu. V tabulce mam barevne sloupce. if ARow > 0 then Begi…
Mirek Mastny 03.11.2011 07:28
Mirek Mastny
Protoze nerespektujes FixedCols. Natvrdo nastavujes CV.Brush.Color := clWhite pro vsechny sloupce. A…
Jan Fiala 03.11.2011 07:37
Jan Fiala
Dik moc.Vše funguje. Měl bych ještě dotaz ohledně toho zdrojaku na vykreslovaní těch obrázku, na kte…
Mirek Mastny 04.11.2011 06:38
Mirek Mastny
Tohle ti fungovat nebude. Ale osobne nechapu, proc ID toho obrazku nevkladas primo do bunky, do kter…
Jan Fiala 05.11.2011 10:49
Jan Fiala
Ale osobne nechapu, proc ID toho obrazku nevkladas primo do bunky, do ktere jej chces vykreslit. Pak…
Mirek Mastny 05.11.2011 16:26
Mirek Mastny
Ty vkladas ID do jine bunky (sloupec 2) a vykreslujes sloupec 1. Proc? Kdybys to vkladal primo do sl…
Jan Fiala 05.11.2011 21:34
Jan Fiala
Asi si nerozumíme. Já bych chtěl vkládat ten obrázek přímo za běhu, tak jak jsem to uved v mem první…
Mirek Mastny 05.11.2011 22:01
Mirek Mastny
Než jsem se rozhod požadat tady o pomoc tak jsem to měl takto. dIcmpClient.ReceiveTimeout := 1000;…
Mirek Mastny 05.11.2011 22:20
Mirek Mastny
Tak na to jak vkladat obrazek za běhu v jine proceduře jsem už přišel. procedure TForm1.Button1Cli…
Mirek Mastny 08.11.2011 18:14
Mirek Mastny
Takže všem moc děkuji za ochotu a pomoc. poslední
Mirek Mastny 10.11.2011 06:15
Mirek Mastny

Tak jsem vyzkoušel ten DrawCell a spíš než úspěch se do toho začínám záplatovat.
Funguje to, ale spíš jsem špatně pochopil princip a funkčnost procedury DrawCell.
Pokud chci umístit obrázek jen do 1 buňky tak OK.

procedure TForm1.Button1Click(Sender: TObject);
begin
x:=1;
y:=1;
Canvas.StretchDraw(StringGrid1.CellRect(x,y),Image 1.Picture.Graphic);
StringGrid1.SetFocus;
end;
//------------------------------------------------ ---------------------------
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if (ACol=x) and (ARow=Y) then
StringGrid1.Canvas.StretchDraw(Rect,Image1.Picture .Graphic);
end;
//------------------------------------------------ -------------------------------
Co potřebuji já.
Mam StringGrid jen se 2 sloupci(ID +1)
Ve sloupci 1 mam odkazy na FTP servry.
Program si pravidelně zjišťuje pomoci pingu zda je FTP dostupné a pokud ne, tak chci aby zobrazil u toho FTP v ID sloupci ikonu s vykřičníkem.

Pokud jsem to dobře pochopil tak procedura DrawCell běží furt dokola nezávisle na programu a furt dokola vybarvuje StringGrid.
Tak mně napadlo vytvořit ještě 1 pracovní buňku do které se bude zapisovat zda je FTP dostupné nebo ne pomoci 0 a 1 a v DrawCell to testovat a vybarvovat.
A funguje to.

procedure TForm1.FormCreate(Sender: TObject);
begin
StringGrid1.Cells[2,2]:= '1';
StringGrid1.Cells[2,6]:= '1';
end;
//------------------------------------------------ -------------------------------------------------- --
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
for i := 1 to StringGrid1.RowCount do
begin
if StringGrid1.Cells[2,i]= '1' Then
begin
StringGrid1.Canvas.StretchDraw(StringGrid1.CellRec t(0,i),Image1.Picture.Graphic);
end;
//------------------------------------------------ ---------------------------------------

Když však při běhu programu zapíšu do 3 sloupce další 1 tak se nic neděje.
//----------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
begin
StringGrid1.Cells[3,8]:= '1';
end;
//---------------------------------------------
Proč ????

Pokud jsem to dobře pochopil tak procedura DrawCell běží furt dokola nezávisle na programu a furt dokola vybarvuje StringGrid.

Tak toto myslím si nie je pravda, vykresľuje sa len ak je to potreba...
Skús "vynútiť" vykreslenie: StringGrid1.Refresh alebo StringGrid1.Repaint.

Edit: Rowcount je počet riadkov - napr.3 , ale ak sa nemýlim, tak Row je číslované od 0..rowcount-1, teda určite Ti niekedy nastane prípad "out of range" ;-)

Pochopil jsi to spatne.
Bud StringGrid uzivatelsky vykreslujes nebo ne.
Pokud vykreslujes, musis vykreslovat vsechny bunky.
OnDrawCell ti vraci bunku, kterou StringGrid chce vykreslovat. V pripade, ze je to bunka s obrazkem, tak vykreslis obrazek, kdyz tam ma byt text, tak vypises text.

Priklad na OnDrawCell mas v helpu, tam jsi se dival?

Pokud chces vykreslovat vic obrazku, dej je do ImageListu. Pro vykresleni pak pouzijes primo metodu ImageListu: ImageList.Draw(), kteremu reknes na jaky canvas, kam a jaky index obrazku z imagelistu

Tak toto ale vubec nechapu.
Jak na barevny text ve sloupci neno barevne bunky vim.
Přikladu je na netu spousta.
Ale jak na ty obrazky nechapu protože tam muže byt obrazek nebo ne.

Nepomoh by někdo, prostě tady jsem se zasek a nevim jak dal.

Prostě pokud bude ve sloupci 3 v nějake bunce 1 tak bude v ID bunce vykreslen obrazek s Image1.Picture.Graphic
pokud tam bude 0 tak obrazek bude smazan.
Nebo pokud je nějake jednoduchši řešeni.
Oč mi jde jsem již psal, hlidat ty FTP pomoci pingu.

OnDrawCell ti vraci primo rect pro vykreslovani a bunku, kterou vykreslujes.
Pises, ze texty vykreslovat umis, takze s tim problem neni.

Podobne veci se delaji opravdu pres ImageList. Takze obrazek misto toho, abys jej dal do TImage dej do ImageList ve velikosti, v jake jej chces vykreslovat. Predpokladejme, ze tam mas jen jeden obrazek.
Znovu opakuju, ze OnDrawcell ti vraci souradnice bunky ACol a ARow a ty musis vykreslovat jen prislusnou bunku!
Pak by to mohlo vypadat nejak takto (je to z hlavy, takze se omlouvam za pripadne chyby):

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
   Rect: TRect; State: TGridDrawState);
begin
   with TStringGrid(Sender) do
   begin
      Canvas.Brush.Color := clWindow;
      Canvas.FillRect(Rect);
      if (ACol=0) then
      begin
         if (StringGrid1.Cells[2, ARow]='1') then
            ImageList.1.Draw(Canvas, Rect, 0);
      end
      else
         Canvas.TextOut(Rect.Left+1, Rect.Top+1, Cells[ACol, ARow]);
   end;
end;

Děkují moc za pomoc.
Pokud to bylo z hlavy tak jste se docela trefil.
Problém byl jen tady ImageList.1.Draw(Canvas, Rect, 0);
Opravil jsem to takto ImageList.Draw(Canvas,Rect.Left,Rect.Top,0);
Problém je že to děla úplně to samé co mi předtím.
Pokud jsou při spuštění programu ve sloupci nějake 1 tak to vykresli.
Pokud však přidám nějakou za běhu, tak se nic neděje.

Podobne veci se delaji opravdu pres ImageList. Takze obrazek misto toho, abys jej dal do TImage dej do ImageList

Tak jsem zkoušel a žádná slava, oproti Image nepodporuje PNG s průhledným pozadím a vybarvi ho černě.:-/

Jinak pro pme: PingInfoView znám a kdysi jsem používal.
Pokud by šel ručně změnit HostName, tak by byl docela dobry.
Pokud má člověk jen par koustu na hlídaní a má ty IP v hlavě tak je to OK.

Neni to pravda. Podporuje pruhledne pozadi. Pri pradavani do ImageList urcujes masku.

Co se tyka pridavani, tvuj problem je v tom, ze zmenis jinou bunky nez chces vykreslit. StringGrid neprekresluje pri zmene bunky cely obsah, ale jen bunku, kterou jsi zmenil.
Takze postup:
Zmenim bunku
Zavolam StringGrid.Repaint, pripadne StringGrid.Refresh

Moh byh ještě jeden dotaz ohledně StringGridu.
V tabulce mam barevne sloupce.

if ARow > 0 then
Begin
CV := TStringGrid(Sender).Canvas;
sCellString := TStringGrid(Sender).Cells[ACol, ARow];

case ACol of
1,2,4: if (gdSelected in State) or (gdFocused in State) then CV.Font.Color := clblack
Else CV.Font.Color := clblack;
3,6: if (gdSelected in State) or (gdFocused in State) then CV.Font.Color := clRed
Else CV.Font.Color := clRed;
5,7: if (gdSelected in State) or (gdFocused in State) then CV.Font.Color := clBlue
Else CV.Font.Color := clBlue
end;
CV.Brush.Color:=clWhite;
CV.Brush.Style:=bsSolid;
CV.FillRect(Rect);
CV.TextOut(Rect.Left -2 , Rect.Top +2, sCellString);
end;
end;

Proč se vertikal ID sloupce zobrazuji takto
2a8kaia.jpg
a nemaji šedou barvu jak jak maji mit a jak ma horizontalni ID .
Kod vubec nezasahuje do 0 ID buněk.

Dik moc.Vše funguje.
Měl bych ještě dotaz ohledně toho zdrojaku na vykreslovaní těch obrázku, na který nepospíchám, takže až budete mít někdy chvilku času.
Nemohu přijít na to jak to překreslovaní vyřešit, kdybych vkládal do ID buňky obrázek přímo a ne přes to 1,0.

Kdybych dal přímo do nějakého tlačítka
StringGrid1.Canvas.StretchDraw(StringGrid1.CellRec t(2,0),ImageList.1.Draw(Canvas, Rect, 0));

Tohle ti fungovat nebude.
Ale osobne nechapu, proc ID toho obrazku nevkladas primo do bunky, do ktere jej chces vykreslit. Pak bys to mel bez problemu.
Obrazku muzes mit spoustu, nastrkas je do ImageListu a podle toho, jaky obrazek chces vykreslit, tak proste nastavis index toho obrazku do bunky. A ImageList nechas vykreslit obrazek a index obrazku vezmes z bunky.

Ale osobne nechapu, proc ID toho obrazku nevkladas primo do bunky, do ktere jej chces vykreslit. Pak bys to mel bez problemu.
Obrazku muzes mit spoustu, nastrkas je do ImageListu a podle toho, jaky obrazek chces vykreslit, tak proste nastavis index toho obrazku do bunky. A ImageList nechas vykreslit obrazek a index obrazku vezmes z bunky.

Ja take ne :-D
Bude to asi tim že jsem lama.:-x

Nějaky přiklad jak na to by nebyl.;-)

Ty vkladas ID do jine bunky (sloupec 2) a vykreslujes sloupec 1. Proc? Kdybys to vkladal primo do sloupce, kam chces vykreslit obrazek, bude ti to fungovat primo.
Ze sloupce si prectes cislo a pouzijes jej jako parametr (index obrazku) pro funkci ImageList.Draw()
Tim, ze budes menit bunku, do ktere vykreslis obrazek, nebudes pak muset pouzivat zavolani Refresh StringGridu.

Priklady uz jsi dostal.

Asi si nerozumíme.
Já bych chtěl vkládat ten obrázek přímo za běhu, tak jak jsem to uved v mem prvním postu s tým Image1.

Třeba takto ale ne s použiti Image1 ale ImageList jak jste mi doporučil.

procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1.Canvas.StretchDraw(StringGrid1.CellRec t(1,1),Image1.Picture.Graphic);
end;

procedura DrawCell by se starala jen o překreslovaní.

IdIcmpClient.ReceiveTimeout := 1000;
IdIcmpClient.Host := kontrolovanaadresa;
IdIcmpClient.Ping();
if testpingu = 1 then StringGrid1.Cells[10,i]:= '1'; // funkčni ping
if testpingu = 0 then StringGrid1.Cells[10,i]:= '0'; // nefunkčni ping
end;
StringGrid1.Repaint;
end;

Misto toho vkladaní 1,0 přimo vykreslovat ten obrazek.

Než jsem se rozhod požadat tady o pomoc tak jsem to měl takto.

dIcmpClient.ReceiveTimeout := 1000;
IdIcmpClient.Host := kontrolovanaadresa;
IdIcmpClient.Ping();
if testpingu = 1 then StringGrid1.Cells[10,i]:= clear; // Funkční ping
if testpingu = 0 then StringGrid1.Canvas.StretchDraw(StringGrid1.CellRec t(0,1),Image1.Picture.Graphic); // nefunkčni ping

Tak bych to take chtěl nechat ale jen vyměnit ten Image1 za ImageList.1 a nějak vyřešit to překreslovaní.

Tak na to jak vkladat obrazek za běhu v jine proceduře jsem už přišel.

procedure TForm1.Button1Click(Sender: TObject);
begin
if a = 5 then ColorRow := 5; // pokud a = 5 nakresli obrazek do 5 řadku
StringGrid1.Repaint;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
begin
begin
with TStringGrid(Sender) do
begin
Canvas.FillRect(Rect);
if (ACol=0) then
begin
if (ARow = ColorRow) then
ImageList1.Draw(Canvas,Rect.Left,Rect.Top,0);
end
else
Canvas.TextOut(Rect.Left+1, Rect.Top+1, Cells[ACol, ARow]);
end;
end;
end;

Ale to překreslovaní sam nedam :-/
Po znměně ColorRow zmizne.
Help Me.

Zpět do poradny Odpovědět na původní otázku Nahoru