Jít do obsahu fóra

Nejsi přihlášen. Přihlas se nebo se zaregistruj.


(Stránka 1 z 2)

Audioweb.cz » Smetiště » Pomoc s Delphi7 Personal

  Stránky: 1 2 »»»

RSS

Příspěvky [1 až 20 z 36]

Téma: Pomoc s Delphi7 Personal

Začal jsem si hrát s Delphi7 Personal a mám problém. Program, co si dělám, dopočítává TSka a jako výstup má umět UNT LspCADu. Ano, mluvím k tobě, Boramyre, vím, že jsi dělal Konvertor wdr>unt a mě by zajímalo, co vlastně unt soubor je, jak ho editovat a co a jak v Delphi, aby to tento výstup umělo.

Dále bych měl maličkosti všeobecně pro všechny:

1/ Do Editu napíšu ",3", chci, aby se před "," vždy doplnila nula, nejlépe odjetím z Editu (to bych si přiřadil).
2/ Chci-li vymazat všechny Edity, nebudu přece psát Edit1.Text.Clear; Edit2.Text.Clear; až po třicáty Edit... nejde to nějak sloučit?
3/ Mimo UNT by to mělo umět ukládat i do TXT a obrázku PNG, hůř BMP. K tomuto ukládacímu oknu jsem se zatím ani nedostal.

Re: Pomoc s Delphi7 Personal

Mrknu se po zdrojáku, protože pokud se pamatuju, tak UNT je binární, ale struktura je jednoduchá, myslím, že jen čísla naházená ve správném pořadí a formátu za sebou. Já to tenkrát louskal HexEditorem na pokusných souborech.

Ad 1) tady to půjde jednoduše, třeba :

if Edit1.Text[1] = ',' then Edit1.Text = '0'+Edit1.Text;

Bylo by však lépe, kdyby se navíc zajistilo, že bude použit správný oddělovač desetinného místa. Kdyby měl někdo v systému nastavenou tečku namísto čárky, tak ten následný převod klekne. To, jaký oddělovač desetinné pozice je v systému nastaven zjistíš z proměnné DecimalSeparator. Asi by bylo nejjednodušší projít všechny znaky daného čísla a nečíslné zaměnit za DecimalSepartor. To už je celkem blbuvzdorné, ne úplně, ale dost. Proti náhodné mezeře na začátku či konci čísla se hodí funkce Trim.

Po kupě by se to dalo udělat třeba takhle :

var i:integer;

for i:= 1 to Length(Edit1.Text) do
if (Edit1.Text[i] < '0') or (Edit1.Text[i] > '9') then Edit1.Text[i]:=DecimalSeparator;

Edit1.Text:=Trim(Edit1.Text);

if Edit1.Text[1] = DecimalSeparator then Edit1.Text = '0'+Edit1.Text;

No a nebo přes funkci StrScan, ale tam si nejsem jistý, jestli by to bylo jednodušší, ta funkce pracuje s PChary.

Ad 2) Napadá mě, že by se to dalo udělat takhle :

var i:integer;

for i:= 0 to Form1.ControlCount -1 do
if (Form1.Controls[i] is TEdit) then (Form1.Controls[i] as TEdit).Clear;

To by mělo smazat všechny Edity na Form1, ale nutno zkusit.

Ad 3) Ukládání by se dalo udělat všelijak. Text je asi nejjednodušší připravit si pěkně do TMemo či TRichEdit, pokud to má být někde vidět, nebo interně do TStringList a pak už jen zavolat Memo.Lines.SaveToFile nebo StringList.SaveToFile.

Jakoukoliv bitmapu si uděláš v komponentě TImage uložíš jednoduše Image.Picture.SaveToFile

Pro PNG si budeš asi muset něco sehnat, ale nějaká taková komponenta nebo knihovna by měla být po ruce. Vím určitě, že jsem se kdysi setkal s komponentou, která uměla číst a ukládat GIF.

Pro ukládání UNT souborů jsem tenkrát napsal tohle :

unit UConv;

interface

type

 TUntHead = record
             StartID  : word;                    // 100
             Unknown1 : single;                  // Default 0
             Unknown2 : single;                  // Default 0
             Reb      : single;                  // Default 0
             Leb      : single;                  // Default 0
             Manuf    : array [1..100] of char;  // Manufacturer
             Model    : array [1..100] of char;  // Model
             Typ      : word;                    // 0 - 6
             Sd       : double;                  // m^2
             r        : double;                  // m
             Vas      : double;                  // m^3
             Cms      : double;                  // N/m
             Cas      : double;                  // m^5/N
             Qms      : double;                  // []
             Qes      : double;                  // []
             Qts      : double;                  // []
             P        : double;                  // W
             Xmax     : double;                  // m
             AirGap   : double;                  // m
             VoiceCoil: double;                  // m
             Mmd      : double;                  // kg
             Mms      : double;                  // kg
             Rms      : double;                  // Ns/m
             Fs       : double;                  // Hz
             BL       : double;                  // N/A
             Re       : double;                  // Ohm
             Le       : double;                  // H
             Cross    : word;                    // Crosscalc (1=True)
             Len      : word;                    // Comment Length
            end;

 TUntNote = array[1..601] of Char;

 TUntTail = record
             DualCoil : word; // (1=True)
             EndID    : word; // Default 12345
            end;

 TUntFile = record
             Head : TUntHead;
             Note : TUntNote;
             Tail : TUntTail;
            end;

procedure SetUntToDefault(var U: TUntFile);
procedure SaveUntFile(const U: TUntFile; const S:String);

implementation

uses Classes, SysUtils;

procedure SetUntToDefault(var U: TUntFile);
begin
 with U.Head do
  begin
  startid:=100; unknown1:=0; unknown2:=0;
  reb:=0; leb:=0; typ:=1; sd:=0; r:=0; vas:=0;
  cms:=0; cas:=0; qms:=0; qes:=0; qts:=0; p:=0;
  xmax:=0; airgap:=0; voicecoil:=0; mmd:=0;
  mms:=0; rms:=0; fs:=0; bl:=0; re:=0; le:=0;
  cross:=0; len:=1;
 end;
 U.Tail.DualCoil:=0;
 U.Tail.EndID:=12345;
 FillChar(U.Head.Manuf,100,0);
 FillChar(U.Head.Model,100,0);
 FillChar(U.Note,601,0);
end;

procedure SaveUntFile(const U: TUntFile; const S:String);
var f:TFileStream;
begin
  f:=TFileStream.Create(S,fmCreate);
 try
  f.WriteBuffer(U.Head,SizeOf(U.Head));
  f.WriteBuffer(U.Note,U.Head.Len);
  f.WriteBuffer(U.Tail,SizeOf(U.Tail));
 finally
  f.free;
 end;
end;

end.

Re: Pomoc s Delphi7 Personal

Od toho nejjednoduššího:

if Edit1.Text[1]=',' then Edit1.Text:='0'+Edit1.Text; funguje hezky, ale jak jsi psal, text nesmí začínat jinak.


U for i:=1 to Length(Edit1.Text) do
if (Edit1.Text[i]<'0') or (Edit1.Text[i]>'9') then Edit1.Text[i]:=DecimalSeparator;
Edit1.Text:=Trim(Edit1.Text);
if Edit1.Text[1]=DecimalSeparator then Edit1.Text:='0'+Edit1.Text;

mě to vypisuje [Error] Unit1.pas(322): Left side cannot be assigned to a kurzor bliká u DecimalSeparator na druhém řádku.


var clr: integer;
begin
for clr:=0 to Form1.ControlCount -1 do
if (Form1.Controls[clr] is TEdit) then (Form1.Controls[clr] as TEdit).Clear;
funguje hezky, ale zdroják nechápu.


Umím ukládat do TXT:
SaveDialog1.FileName:=Edit26.Text;
if SaveDialog1.Execute then
Memo1.Lines.SaveToFile(SaveDialog1.FileName+'.txt');

a i BMP (ScreenShot), tohle jsem si na netu našel a poupravil událost na tlačítko, aby to ukládalo do souboru:
procedure ScreenShot(Bild: TBitMap);
var
c: TCanvas;
r, t: TRect;
h: THandle;
begin
c := TCanvas.Create;
c.Handle := GetWindowDC(GetDesktopWindow);
h := GetForeGroundWindow;
if h <> 0 then
GetWindowRect(h, t);
try
r := Rect(0, 0, t.Right - t.Left, t.Bottom - t.Top);
Bild.Width := t.Right - t.Left;
Bild.Height := t.Bottom - t.Top;
Bild.Canvas.CopyRect(r, c, t);
finally
ReleaseDC(0, c.Handle);
c.Free;
end;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
ScreenShot(Image1.Picture.Bitmap);
SaveDialog2.FileName:=Edit26.Text;
if SaveDialog2.Execute then
Image1.Picture.Bitmap.SaveToFile(SaveDialog2.FileName+'.bmp');
end;
Co tam vidíš přebytečnýho, jak by se to dalo zjednodušit?


To ukládání UNT souborů vypadá morbidně, to si nechám na konec.

Díky moc. smile

Re: Pomoc s Delphi7 Personal

Zdá se, že TEdit.Text nemá implementovanou možnost zápisu do jednotlivých znaků. Tak holt přes pomocnou proměnnou. Toto už funguje, právě jsem to vyzkoušel.

var i:integer;
    s:string;
begin
 s:=Trim(Edit1.Text);
 for i:=1 to Length(s) do
 if (s[i]<'0') or (s[i]>'9') then s[i]:=DecimalSeparator;
 if s[1]=DecimalSeparator then s:='0'+s;
 Edit1.Text:=s;
end;

No a ten druhej kód mě docela mile překvapil, že funguje, protože jsem ho nikdy nepoužil. Ale vcelku by to mělo fungovat takhle :

TForm.Controls je pole objektů TControls. Jsou to vlastně ukazatele na všechny objekty co jsou na formuláři odvozené od TControls, což jsou minimálně všechny grafické komponenty. TForm.ControlsCount je pak jejich počet.
No a teď stačí ve smyčce procházet všechny, testovat je, zdali jsou "kompatibilní" s TEdit. Přesněji řečeno jestli jsou přímo typu TEdit, nebo alespoň potomci TEdit, což dělá operátor "is". Pokud ano, tak je třeba je přetypovat z TControl na TEdit a zavolat jejich funkci Clear. To tam dělám tím operátorem "as" který vrací referenci na stejný objekt, ale v požadovaném typu.

No a v tom kódu co jsi sem dal na to ukládání screenshotu asi nic nezjednodušíš. Akorát pokud to dobře chápu, tak je to kód pro screenshot aktivního okna (což tedy může být i desktop), ale nikoliv vždy celé obrazovky. To je záměr?

(upravil Boramyr 4. 3. 2009 15:00)

Re: Pomoc s Delphi7 Personal

No a to ukládání UNT je jednoduché, akorát to vypadá, že je toho dost. Používá se to takhle :

var u:TUntFile;
begin
SetUntToDefault(u);   // Inicializace, přece jen některé hodnoty nejsou defaultně nulové
// Teď to jen naláduješ hodnotama
u.head.manuf:= 'Seas';
u.head.model:= 'L300RLY/P';
u.head.vas:=150;
u.head.qes:=0.4;
// atd...
u.note:='Toto je nadupanej Seasí basák, co ještě nevymysleli a nevymyslí';
u.head.len:=Length(u.note); // Toto udává, jak dlouhý komentář následuje (max 600 zn.)
u.head.type:=1;  // Toto udává, jestli jde o bas, či co. Mění jen ten obrázek ve schématu
u.head.cross:=0; // Nula znamená, že LspCAD nemá kontrolovat kolize parametrů
u.tail.dualcoil:=0; // Není to dvojcívkáč
// tak, a teď už jenom uložíme
SaveUntFile(u,'megabass.unt');
end;

Re: Pomoc s Delphi7 Personal

Funguje, jen to padá pokud v Editu nic není, zkoušel jsem except, else, ale asi blbě. Chybu to ukazuje v řádku:
if s[1]=DecimalSeparator then s:='0'+s;

Dík za vysvětlení.

Ano, to je záměř. Prostě screennout aktivní okno programu ať se nemusí dávat Alt+PrintScreen a ukládat to. Teď ještě jak to exportovat alespoň do GIFu... ale jsem moc rád i za tohle.

Lamadotaz, tak jako všechny: Takže UNT vypisovat do Mema ani nemusím?

(upravil Boramyr 4. 3. 2009 16:42)

Re: Pomoc s Delphi7 Personal

No jasně, to jsem přehlíd. Když bude text délky nula tak je kravina číst jeho první znak.
Tak to přepiš na "if Length(s) > 0 then if s[1] = atd..." a vymalováno.
Nebo ten řádek napiš jako "if (Length(s) > 0) and (s[1] = DecimalSeparator) then s:='0'+s;"
V normálním nastavení Delphi totiž nevyhodnocuje podmínku celou, pokud je už dřív jistý její výsledek. V tomhle případě to skončí už po zjištění, že je délka nulová a fungovat to bude.

Co se týče unt, tak ne, tohle je kompletní uložení. Ono by to ani přes nějaké memo nefungovalo, protože memo ti uloží text, ale unt je binární. Mimochodem, pokud bys chtěl dělat nějaký text na uložení, třeba FRD a podobný šaškárny, který není třeba někde zobrazit, ale je třeba je jen uložit, tak to jde s výhodou takhle :

var sl:TStringList;
begin
 sl:=TStringList.Create;
 sl.add('nějaký text...');
 // atd...
 sl.SaveToFile('soubor.txt');
 sl.Free;
end;

Třída TStringList je docela šikovná na práci s řádkami textu. Umí to i pár základních věcí, jako je řazení, hledání, vkládání a podobné šaškování s řádky.

Re: Pomoc s Delphi7 Personal

Tak to vypadá, že UNT ukládání budu muset nahradit WDR. Nebo neměl bys kompletní zdroják Konvertoru? Totiž by mě zajímalo, ja tenhle program ty data z WDR sosá a co s nima pak dělá... Koukal jsem na UNT skrz hex editor a nějak se neorientuju, nic nevidím. sad

Re: Pomoc s Delphi7 Personal

Jasně že mám, v původním zipu s konvertorem jsou přibalené i zdrojáky. http://home.tiscali.cz:8080/~cz921339/cnvrt.zip Předem upozorňuji, že zrovna čtení WDR je tam udělané velice stupidně, protože se mi zrovna nechtělo nic vymýšlet. Postup je sice funkční, ale selže jakmile bude v poředí položek jakákoliv změna nebo výpadek. Přitom by to mohlo fungovat naprosto hladce a obecně kdybych si tenkrát nebyl línej přečíst help k TRegIniFile, tahle třída je obsluha právě toho typu souboru co je WDR.

Re: Pomoc s Delphi7 Personal

Zatím řeším detaily: Chci, aby stiskem šipky nahoru na klávesnici se zvedla hodnota v Editu o 0.1, tohle mi funguje pod klávesou #8 (backspace). Ale pod šipkami, ani čímkoliv jiným, ne. Proč? Měla by to být #38 a 40, viz Delphi Key Values.

procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
var value: real;
begin
try
Value:=StrToFloat(Edit2.Text);
Value:=Value+1;
if not (Key in ['0'..'9', '.', ',', #8]) then Key:=#0;
if Key=#8 then Edit2.Text:=FloatToStr(Value);
except on EConvertError do Edit2.Text:='';
end;
end;

(upravil MaBat 18. 3. 2009 20:14)

Re: Pomoc s Delphi7 Personal

Jestli to nebude proto, že "if not (Key in ['0'..'9', '.', ',', #8]) then Key:=#0;", čili, pro všechny ostatní znaky si tam přiřadíš #0. Ty podmínky prohoď, nebo přidej kódy šipek do tý testovaný množiny... (neměl by tam být ještě enter a tabelátor?)

Edit: Áá, tak všechno zpět, do KeyPressu se zřejmě šipky ani nedostanou, jen skutečný znaky (evidentně plus backspace). Musíš použít KeyDown/Up.

Re: Pomoc s Delphi7 Personal

Ty kódy jsem tam samozřejmě předtím přidal, káždopádně dík za ten KeyDown, vyřešeno, a na plus/minus: smile

procedure TForm1.Edit5KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var value,minus,plus: real;
begin
try
value:=StrToFloat(Edit5.Text);
plus:=value+0.1;
minus:=value-0.1;
if key=vk_add then Edit5.Text:=FloatToStr(plus);
if key=vk_subtract then Edit5.Text:=FloatToStr(minus);
except on EconvertError do Edit5.Text:='';
end;
end;

Re: Pomoc s Delphi7 Personal

Boro, další drobnost, v Edit26 píšu typ repra, no a obsahuje-li takovéto slovo lomítko, nechce mi vyskočit okno s uložením, jak bys na to šel?

SaveDialog1.FileName:=Edit26.Text;
if SaveDialog1.Execute then
txt.SaveToFile(SaveDialog1.FileName);

A další věc, dá se nějak upravit velikost aplikace? Totiž jde jen o pár matematických vzorců plus pár blbin okolo a exe soubor má přes 400kB (pas soubor má 21kB). I program, co nic neumí, má skoro těch 400kB. Vidívám prográmky, co toho umí dost a pohybují se i kolem 100kB.

(upravil Boramyr 21. 5. 2009 20:20)

Re: Pomoc s Delphi7 Personal

Asi chceš nabídnout typ repra jako název ukládaného souboru, co? A jelikož lomítko není povolený znak pro název souboru, tak to nefunguje. Já bych udělal to, že před tím voláním co jsi tu napsal bych prošel ten Edit26.Text znak po znaku a každé lomítko nahradil podtržítkem. Možná ještě lepší by bylo nahrazovat podtržítkem cokoliv co neodpovídá nějaké rozumné množině znaků.

Něco jako :

Nazev:= Edit26.Text;
for i:= 1 to length(Nazev) do
if not (Nazev[i] in ['a'..'z', 'A'..'Z', '0'..'9', '-', ' ']) then Nazev[i]:='_';

To by mohlo fungovat, nezkoušel jsem.

Co se týče velikosti, tak těch 400kB je holt daň za pohodlí v moderních vývojových prostředích. V nastavení projektu se dá zaškrtnout, aby se obsah runtime knihoven nelinkoval k aplikaci. Tím sice uděláš program pár desítek kB velký, ale zase bude závislý na přítomnosti těch knihoven v systému. Druhá možnost je použít nějaký pakovací prográmek, já používal tohle : http://www.un4seen.com/petite/

Re: Pomoc s Delphi7 Personal

Boro, díky. Jen to má jednu mouchu, je-li v názvu toho repra tečka (třeba PDčka), znaky za ní to ignoruje, končí to tedy tím PD.

Re: Pomoc s Delphi7 Personal

Přinejhorším budeš muset na podtržítka převádět i tečky. Napadlo mě, že pokud máš nastavný SaveDialog.DefaultExt a pak ti něco za tečkou neodpovídá té nastavené příponě, tak to zlobí.

Re: Pomoc s Delphi7 Personal

Limp ukládá do csv, asi víš o co jde.

Z něj potřebuji vybrat hodnoty a naskládat je do Editů, SaveDialog, pokud jde o text, je brnkačka, ale Open je jiná, jak zjišťuji. Nevím, jak se v tom textu dostat na určitou pozici, žeby fígl najdi čárku s mezerou, přečti a pak tu druhou?

Re: Pomoc s Delphi7 Personal

No, on nějaký blokový přístup ani nemá smysl, když jsou položky různě dlouhé. Musí se to udělat jako sekvenčcní čení a narozdíl od matlabu, tady to delphi asi moc neulehčuje.

Já bych si zaprvé napsal funkci, která by mi převedla jeden string (řádka v souboru) na tři (jednotlivé položky). Pak bych si vytvořil TStringlist a obsah souboru pomocí LoadFromFile do toho načetl. Ve stringlistu budu řádky jako jednotlivé položky no a ty si pak můžu rozkouskovat tou připravenou funkcí a nějak více či méně inteligentně cpát kam je potřeba.

Co se týče toho rozdělení stringu na tři podle čárek, tak hledáním a kopírováním by to určitě šlo, ale lepší by asi bylo udělat to jednodušeji. Prostě brát to znak po znaku a skládat je do první proměnné, dokud se nenarazí na čárku, pak pokračovat do druhé proměnné až do další čárky atd... akorát si ještě pohlídat mezery a konce řádků a hotovo.

Re: Pomoc s Delphi7 Personal

Mám Image, jako Picture obrázek grafu, do něj jako Canvas.Pixels vykresluji křivku. Problém je v tom, že nepřicházím na to, jak ji smazat, křivky se tak přes sebe překrývají. Nejsnadnějc snad znovunačíst obrázek grafu...

Předem děkuji.

Re: Pomoc s Delphi7 Personal

Co takhle dát dvě komponenty Image přes sebe, horní nastavit průhlednost, do spodní dát obrázek grafu a křivky čmárat/mazat v té horní?

Příspěvky [1 až 20 z 36]

  Stránky: 1 2 »»»

Audioweb.cz » Smetiště » Pomoc s Delphi7 Personal

Podobná témata


~±«|»¼½¾²³&@µΩπØ$£