Artykuły >>
Projekty >>
Downloads >>
Serwis >>
Mając dwadzieścia lat myślałem tylko o kochaniu. Potem kochałem już tylko myśleć. Albert Einstein
/ LHP / serwis
Lukas Delphi FAQ

Informacja o prawach autorskich

Lukas FAQ jest rozprowadzane na ogólnych zasadach licencji typu freeware. Zastrzegam sobie wyłączne prawo do modyfikacji tego dokumentu. Jeśli "pożyczasz" FAQ ma ono pozostać w nie zmienionej formie (dozwolone są jedynie poprawki "kosmetyczne"), podpisane moim imieniem i nazwiskiem (Łukasz "Lukas" Wyporek), adresem strony (http://www.lukas-home-page.ovh.org/), i e-mailem (lukas.home.page@gmail.com). Jeśli spełnisz te warunki to nie widzę problemu. Było by miło abyś napisał przed tym do mnie i podał stronę na której ów FAQ będzie się znajdować (ale nie jest to konieczne) (napisz do mnie).


  1. Jak wywołać błąd w środowisku Delphi, wpisując jedynie spreparowany kod?
  2. Jak animować tekst z cieniem na formie ?
  3. Jak powiększyć dla danej procedury globalnie zadeklarowaną tablicę?
  4. Jak zamknąć okno znajdujące się np. w punkcie (20, 150)?
  5. Jak w trakcie pracy programu stworzyć komponent, obsługiwać jego zdarzenia i poznać jaką ma nazwę?
  6. Jak skonwertować liczbę z systemu szesnastkowego na system dziesiętny?
  7. Jak skonwertować liczbę z systemu dwójkowego na system dziesiętny?
  8. Jak przeskakiwać do kolejnych komponentów TEdit tak jak przy wprowadzaniu kodu aktywacyjnego w Office 2000?
  9. Jak napisać wygaszacz ekranu ?
  10. Jak odczytać listę zainstalowanych w systemie aplikacji (jak odczytać listę z apletu "Dodaj/Usun programy")?
  11. Jak utworzyć zbiór i sprawdzić czy dany element znajduje się w zbiorze?
  12. Jak zmienić wartość stałej? ;)
  13. Jak zmienić kolor na HEX?
  14. Czy można jakoś inaczej zapisać operator mod?
  15. Jak wyszukać wszystkie katalogi na dysku?
  16. Jak nagrywać dźwięk tak, by mieć kontrole nad buforem w czasie rzeczywistym?
  17. Dlaczego w moim programie sieciowym (korzystam z czystego Winsock API) serwer zgłasza się na innym porcie niż podany w parametrach funkcji?
  18. Jak poprawnie zainstalować DSPack w Delphi 6?
  19. Jak łatwo odczytać nazwę, producenta, prędkość zainstalowanego procesora?
  20. Co zrobić by w ColorBoxsie nazwy kolorów były po Polsku?
  21. Czy przypisanie do zmiennej typu Byte wartości większej niż 255 skutkuje przepełnieniem?
  22. Jak zrobić okienko do zapisywania bitmapy w ilości kolorów zależnie od wybranej w okienku zapisu opcji?

 

  1. Jak wywołać błąd w środowisku Delphi, wpisując jedynie spreparowany kod?
    Najpierw chciałbym poinformować wszystkich zainteresowanych, że błąd zauważyłem w Delphi 6 Personal, nie wiem jak wspomniane środowisko zachowuje się w nowych wydaniach. Na początku chciałbym zaznaczyć, że uważam to środowisko za najlepsze i najbardziej dopracowane ze wszystkich, coś takiego przytrafiło mi się pierwszy raz. Okazuje się bowiem, iż wpisując odpowiednio spreparowany kod możemy... wywołać błąd środowiska już przy próbie kompilacji (a więc bez uruchamiania programu). Należy wówczas wpisać coś takiego: maskaX : array[0..2,0..2] of integer = (-1,0,1, -2,0,2, -1,0,1); Oczywiście jest to niepoprawny przykład próby zainicjowania tablicy dwuwymiarowej, podając tylko jeden wymiar i to jeszcze przekraczający zadeklarowaną wielkość.
  2. Jak animować tekst z cieniem na formie ?
    Cała procedura jest poniżej. Tworzona jest Bitmapa na której rysowane są dwa teksty: jeden w kolorze szarym i jeden w kolorze czerwonym. Oba teksty przesunięte są od siebie o jeden piksel co sprawia wrażenie cienia. Oba teksty (szary - cień i czerwony - tekst mają tło ustawione jako przezroczyste [bsClear]). Tekst przesuwa się w lewo i jest trzykrotnie wyświetlany w jednym cyklu. procedure TFrAbout.animuj(tekst: string); var Bitmapa: TBitmap; x,x2,y : integer; txtmod : string; begin AnimujRun := True; Bitmapa := TBitmap.Create; Bitmapa.Canvas.Font.Size := 14; Bitmapa.Canvas.Font.Name := 'Courier New'; txtmod := tekst + ' ' + tekst + ' ' + tekst; Bitmapa.Width := Bitmapa.Canvas.TextWidth(txtmod)+2; Bitmapa.Height := Bitmapa.Canvas.TextHeight(txtmod); Bitmapa.Canvas.FillRect(Rect(0,0,Bitmapa.Canvas.TextWidth(txtmod)+2,Bitmapa.Canvas.TextHeight(txtmod))); Bitmapa.Canvas.Brush.Color := clRed; x := Image1.Width; y := 0; Repeat Application.ProcessMessages; Sleep(10); Bitmapa.Canvas.Brush.Style := bsClear; Bitmapa.Canvas.Font.Color := clRed; Bitmapa.Canvas.TextOut(1,1,txtmod); Bitmapa.Canvas.Brush.Style := bsClear; Bitmapa.Canvas.Font.Color := clGray; Bitmapa.Canvas.TextOut(0,0,txtmod); Image1.Canvas.Draw(x,y,Bitmapa); Dec(x); until (x = -3*Image1.Canvas.TextWidth(txtmod)) or (MainForm.Done); Bitmapa.Free; AnimujRun := False; end;
  3. Jak powiększyć dla danej procedury globalnie zadeklarowaną tablicę?
    W procedurze w której chcesz mieć np. większą tablicę piszesz: Po słowie var: Nazwa_tablicy : array of real override; W sekcji pomiędzy begin i end; SetLength(Nazwa_tablicy, High(nazwa_tablicy)+5);
  4. Jak zamknąć okno znajdujące się np. w punkcie (20, 150).
    Do tego służy funkcja WindowFromPoint(). Wystarczy napisać coś takiego: var handle : HWND; begin handle := Windows.WindowFromPoint(Point(20,150)); SendMessage(handle,WM_CLOSE,0,0); Dzięki temu zamkniesz każdy element (włącznie z pulpitem) znajdujący się w danym punkcie.
  5. Jak w trakcie pracy programu stworzyć komponent, obsługiwać jego zdarzenia i poznać jaką ma nazwę?
    // Jak w trakcie pracy programu stworzyć komponent? // Do zmiennych globalnych dodaj (słówko var przed sekcją implementation) var Button : TButton; // W jakiejś procedurze piszesz teraz: Button := TButton.Create( Self ); Button.Parent := Self; Button.Left := 50; Button.Top := 50; Button.Caption := 'Przycisk' ; Button.OnClick := ButtonClick; // Aby obsłużyć zdarzenia, należy utworzyć procedurę ( w sekcji private ): private procedure ButtonClick(Sender : TObject); end; // W Implementation: procedure TForm1.ButtonClick(Sender : TObject); begin ShowMessage('Nacisnąłęś przycisk '+ TButton(Sender).Name ); end;
  6. Jak skonwertować liczbę z systemu szesnastkowego na system dziesiętny?
    Spróbuj zastosować taką pętlę: For z := Length(liczba)-1 Downto 0 Do Begin If liczba[z+1] = 'A' Then buff := buff + (10 * Power(16,x)) else If liczba[z+1] = 'B' Then buff := buff + (11 * Power(16,x)) else If liczba[z+1] = 'C' Then buff := buff + (12 * Power(16,x)) else If liczba[z+1] = 'D' Then buff := buff + (13 * Power(16,x)) else If liczba[z+1] = 'E' Then buff := buff + (14 * Power(16,x)) else If liczba[z+1] = 'F' Then buff := buff + (15 * Power(16,x)) else buff := buff + StrToInt(liczba[z+1]) * Power(16,x); Inc(x); end; Result := FloatToStr(buff);
  7. Jak skonwertować liczbę z systemu dwójkowego na system dziesiętny?
    Użyta tutaj zmienna zakres jest zmienną typu string. Przechowuje ona zera i jedynki przeznaczone do skonwertowania. For z := Length(zakres)-1 Downto 0 Do Begin buff := buff + StrToInt(zakres[z+1]) * Power(2,x); Inc(x); end; Result := FloatToStr(buff);
  8. Jak przeskakiwać do kolejnych komponentów TEdit tak jak przy wprowadzaniu kodu aktywacyjnego w Office 2000?
    Aby "przeskakiwać" do kolejnych komponentów typu TEdit musisz napisać coś takiego i umieścić to w procedurze obsługującej zdarzenie OnChange: if Length(TEdit(Sender).Text) = TEdit(Sender).MaxLength Then fmMainForm.ActiveControl := fmMainForm.FindNextControl(TEdit(Sender), True, True, True);
  9. Jak napisać wygaszacz ekranu ?
    Wygaszacz ekranu to normalny program ze zmienionym rozszerzeniem (zamiast .exe mamy .scr). Po napisaniu pożądanego programu musimy umieścić go w katalogu (domyślnie) C:\Windows . Gdy to zrobimy, wygaszacz pokaże się na liście dostępnych wygaszaczy we właściwościach ekranu. Mówiąc o wygaszaczach nie sposób nie wspomnieć o małym, aczkolwiek istotnym szczególe. Mianowicie, podglądając wygaszacze przez okno "Właściowości ekranu", zauważymy, że nasz wygaszacz, po wybraniu go z listy od razu się nam uruchamia. Dlaczego? Ano dlatego, że nie obsłużyliśmy w nim parametrów przekazywanych do niego wraz z uruchomieniem. Parametry te odczytujemy w naszym programie za pomocą funkcji ParamCount() oraz ParamStr(). Pierwsza z nich określa ile przekazano parametrów do naszego programu, z tym, że należy pamiętać, że parametr o indeksie 0 to ścieżka do programu. Druga funkcja służy do odczytu parametrów, np.: ParamStr(0) zwróci ścieżkę do naszego programu. Wracając do parametrów wygaszaczy, mamy tam następującą sytuację:

    Okno "Właściwości ekranu" uruchamia nasz wygaszacz z następującymi parametrami (w zależności od tego czy ma być on widoczny w małym okienku (małym podglądzie), czy w normalnym, pełnoekranowym podglądzie).
    Nazwy i opisy parametrów przekazywanych przez system Windows do wygaszaczy ekranu
    Akcja Parametr Opis parametru
    Podgląd w małym okienku /p Parametr jest uchwytem okna, w którym mamy wyświetlić podgląd naszego wygaszacza.
    Podgląd na pełnym ekranie /s Gdy Windows chce wyświetlić wygaszacz standardowo (na pełnym ekranie), uruchamia nasz wygaszacz z tym parametrem.
  10. Jak odczytać listę zainstalowanych w systemie aplikacji (jak odczytać listę z apletu "Dodaj/Usun programy") ?
    Stawiamy na formie następujące komponenty (TButton, TListBox, TLabel), powinny mieć nazwy odpowiednio: Button1, ListBox1, Label1.
    Klikamy dwukrotnie na Button1 i uzupełniamy procedurę następująco: procedure TForm1.Button1Click(Sender: TObject); var i : integer; begin i:=0; Reg:=TRegistry.Create; Reg.RootKey:=HKEY_LOCAL_MACHINE; Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Uninstall',False); Reg.GetKeyNames(ListBox1.Items); Reg.CloseKey; For i:=0 To ListBox1.Items.Count-1 Do Begin Application.ProcessMessages; Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+ListBox1.Items.Strings[i],False); If Reg.ValueExists('QuietDisplayName') Then Begin ListBox1.Items.Strings[i]:=Reg.ReadString('QuietDisplayName'); Reg.CloseKey; end; If Reg.ValueExists('DisplayName') Then Begin ListBox1.Items.Strings[i]:=Reg.ReadString('DisplayName'); Reg.CloseKey; end; end; end; Następnie klikamy dwukrotnie na listę (ListBox1) i uzupełniamy procedurę następująco: procedure TForm1.ListBox1Click(Sender: TObject); begin Reg:=TRegistry.Create; Reg.RootKey:=HKEY_LOCAL_MACHINE; Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+ListBox1.Items.Strings[ListBox1.ItemIndex],False); If Reg.ValueExists('QuietUninstallString') Then Begin Label1.caption:=Reg.ReadString('QuietUninstallString'); Reg.CloseKey; end; If Reg.ValueExists('UninstallString') Then Begin Label1.caption:=Reg.ReadString('UninstallString'); Reg.CloseKey; end; Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+ListBox1.Items.Strings[ListBox1.ItemIndex],False); If (not Reg.ValueExists('QuietUninstallString')) and (not Reg.ValueExists('UninstallString')) Then Label1.Caption:='<Brak uninstalatora!>'; Reg.CloseKey; end; To wszystko! Po kliknięciu na Button1 program załaduje nam listę zainstalowanych w systemie aplikacji. Ścieżkę do deinstalatora danej aplikacji możemy uzyskać poprzez kliknięcie na jej pozycję w ListBox (ścieżka wyświetli się w komponencie Label).
  11. Jak utworzyć zbiór i sprawdzić czy dany element znajduje się w zbiorze?
    Tworzymy nowy projekt i przechodzimy do widoku kodu modułu. Odnajdujemy sekcje type (zaraz po sekcji uses). type TForm1 = class(TForm) Button1: TButt... Dodajemy do niej deklarację naszego zbioru w następujący sposób: type SetLitery = set of 'A'..'M'; TForm1 = class(TForm) Button1: TButt... Następnie na formularzu umieszczamy przycisk i klikamy nań dwukrotnie. Pojawia się edytor kodu z nowowygenerowaną procedurą obsługi zdarzenia, w którym wpisujemy: If ('B' in Litery) Then ShowMessage('Litera B należy do zbioru!'); To wszystko! Całość powinna prezentować się następująco: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type SetLitery = set of 'A'..'M'; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Litery: SetLitery; begin If ('B' in Litery) Then ShowMessage('Litera B należy do zbioru!'); end; end.
  12. Jak zmienić wartość stałej? ;)
    Wbrew pozorom jest to możliwe! Tworzymy nowy projekt i przechodzimy do widoku kodu. Przed globalną sekcją
    var
    umieszczamy sekcję
    const
    w której deklarujemy naszą stałą. const // Deklaracja naszej stałej stala : string = 'To jest tekst przypisany do stałej'; Przechodzimy do widoku formularza (np. wciskając F12) i umieszczamy na nim przycisk. Klikamy na przycisk dwukrotnie - otwiera nam się edytor kodu czekający na wpisanie kodu dla procedury obsługi zdarzenia. Uzupełniamy procedurę następująco: procedure TForm1.Button1Click(Sender: TObject); type // Deklarujemy nowy typ wskaźnikowy (jest to typ wskazujący na jakiś łańcuch znaków) TStringPointer = ^string; var // Deklarujemy naszą zmienną o typie TStringPointer, // czyli deklarujemy zmienną o typie wskaźnikowym, // wskazującą na jakiś łańcuch w pamięci Zmienna : TStringPointer; begin // Wyświetlamy zawartość stałej ShowMessage(stala); // Do naszej zmiennej wskaźnikowej, przypisujemy adres naszej stałej, // czyli po prostu wskazujemy na wartość stałej (podłączamy się pod nią) Zmienna := @stala; // Zmieniamy wartość pod adresem na który wskazuje nasza Zmienna Zmienna^ := 'Haha!!! Udało mi się zmienić wartość stałej!'; // Wyświetlamy zawartość stałej ShowMessage(stala); end; To wszystko! Właśnie udało się nam zmienić wartość stałej, czyli krótko mówiąc, nasza stała... stała się zmienną ;P
  13. Jak zmienić kolor na HEX?
    Utwórz nowy projekt i umieść na nim trzy komponenty: TPanel, TColorDialog, TLabel. Kliknij dwukrotnie na komponent "Panel1" - pojawi się edytor kodu czekający na uzupełnienie procedury obsługi zdarzenia (w tym wypadku kliknięcia). Procedurę uzupełniamy następująco: procedure TForm1.Panel1Click(Sender: TObject); var r,g,b :byte; hexR, hexG, hexB : string; begin // Otworzenia okna ColorDialog1 If not ColorDialog1.Execute Then Exit; // Pobranie koloru wybranego w oknie ColorDialog Panel1.Color := ColorDialog1.Color; // Pobieramy składowe koloru r := GetRValue(ColorDialog1.Color); g := GetGValue(ColorDialog1.Color); b := GetBValue(ColorDialog1.Color); // Tutaj następuje konwersja do systemu heksadecymalnego hexR := Format('%x',[r]); hexG := Format('%x',[g]); hexB := Format('%x',[b]); // Drobne poprawki wyświetlania If hexR = '0' Then hexR:='00'; If hexG = '0' Then hexG:='00'; If hexB = '0' Then hexB:='00'; // Wyświetlenie koloru w postaci heksadecymalnej Label1.Caption := hexR+hexG+hexB; end;
  14. Czy można jakoś inaczej zapisać operator mod?
    Owszem. Operator mod to nic innego jak... może przykładzik: var ppp,x,y : integer; begin x := 14; y := 4; ppp := x - (x div y) * y; // = x mod y ShowMessage(IntToStr(ppp)); W okienku wyświetli się wynik operacji
    x mod y
    . Operacja x mod y to nic innego jak wykonanie działania x - (x div y) * y
  15. Jak wyszukać wszystkie katalogi na dysku?
    Utwórz nowy projekt i posadź na formie dwa komponenty TListBox oraz TButton. Kliknij dwukrotnie na komponent Button1 - pojawi się edytor kodu z nowowygenerowaną procedurą obsługi zdarzenia. Uzupełnij ją następująco: procedure TForm1.Button1Click(Sender: TObject); var rec : TSearchRec; found : integer; DirList : TStringList; posDir : integer; // pozycja na liście katalogów FileList : TStringList; begin DirList := TStringList.Create; FileList := TStringList.Create; DirList.Add('C:\'); // Od jakiego katalogu ma zacząć posDir := 0; { Funkcja zwraca 0 kiedy nie wystąpi w niej błąd (gdy wystapi błąd np. nie ma już żadnego pliku do znalezienia (wszystkie zostały już znalezione) to funkcja zwraca wartość różna od zera)} Repeat found := FindFirst(DirList[posDir]+'*.*',faDirectory,rec); While found = 0 Do begin found := FindNext(rec); if found = 0 Then DirList.Add(DirList[posDir]+rec.Name+'\'); ListBox1.Items := DirList; Application.ProcessMessages; end; FindClose(rec); Inc(posDir); until posDir >= DirList.Count; DirList.Free; FileList.Free; end;
  16. Jak nagrywać dźwięk tak, by mieć kontrole nad buforem w czasie rzeczywistym?
    Pytanie:
    interesuje mnie zaawansowane nagrywanie dźwięku w sposób, by mieć kontrole nad buforem (móc go modyfikować) w czasie rzeczywistym. Dodam, że korzystałem z pakietu DSPack, w którym jest możliwość dostępu do bufora w czasie rzeczywistym, ale według moich doświadczeń nie można go w danej chwili modyfikować. Również DSPack niekiedy się troszkę sypie przy tego typu operacjach (np. niemożność odczytania prawdziwego rozmiaru strumienia będącego buforem podczas działań na nim [może nie tyle niemożność co jego nieprawidłowy rozmiar]). Interesują mnie rozwiązania w czystym API, w DirectX (mam przetłumaczone nagłówki) lub komponenty (o ile takie istnieją).
    Z góry dziękuję wszystkim za pomoc, będę wdzięczny za jakiekolwiek odpowiedzi.
    Łukasz.

    Odpowiedź:
    Wszystkich zainteresowanych tematem odsyłam do strony http://www.un4seen.com/ na której znajduje się biblioteka DLL o nazwie BASS, wraz z przetłumaczonymi nagłówkami dla Delphi (tak więc normalna w użyciu, nie trzeba ręcznie wyławiać funkcji z biblioteki DLL). Ma ona ogromne możliwości, jest bardziej dopracowana niż część audio paczki DSPack (nie występują w niej podobne problemy), jest szybsza, łatwiejsza w obsłudze, bezpłatna do niekomercyjnych zastosowań. Dodatkowo dołączony przykład o nazwie RecordTest pokazuje jak można nagrywać za pomocą BASS.
    Udało mi się za jej pomocą zmodyfikować bufor w czasie rzeczywistym (dla chętnych podaje przykład zmienionej procedury "RecordingCallback" znajdującej się w przykładzie RecordTest, która modyfikuje nagrywany dźwięk w czasie rzeczywistym): function RecordingCallback(Handle: HRECORD; buffer: Pointer; length, user: DWord): boolean; stdcall; var i : integer; probka : ^byte; begin // Modyfikacja bufora for i:=0 to length-1 Do begin probka := Pointer(Integer(buffer)+i); // Teraz zmienna probka^ stanowi pojedynczą próbkę którą możemy dowolnie modyfikować probka^ := probka^ div 2; end; // Koniec modyfikacji bufora // Kopiuje bufor (zmienna buffer) do strumienia zawierającego dźwięk (zmienna WaveStream) Form1.WaveStream.Write(buffer^, length); // Allow recording to continue Result := True; end;
  17. Dlaczego w moim programie sieciowym (korzystam z czystego Winsock API) serwer zgłasza się na innym porcie niż podany w parametrach funkcji?
    Najprawdopodobniej podajesz port w innym formacie niż wymagany. Najczęściej korzystamy z funkcji htons() by przypisać gnieździe numer portu na jakim ma nasłuchiwać. Często zapominamy, że funkcja ta jako parametr przyjmuje zmienną typu Word, nie żadne Integery!. Gdy serwer nasłuchuje na nieporządanym porcie, sprawdź czy Twoja zmienna port jest typu Word, pamiętaj również, że nie można zmiennej port przypisać od razu do rekordu który podamy jako parametr funkcji Bind. Port należy najpierw przekonwertować funkcją htons(nasz_port);
  18. Jak poprawnie zainstalować DSPack w Delphi 6?
    Aby poprawnie zainstalować paczkę komponentów DSPack ułatwiającą obsługę DirectX w Delphi, najpierw musimy ściągnąć potrzebne pliki ze strony www.progdigy.com. Gdy już masz paczkę na dysku, postępuj zgodnie z poniższymi krokami:
    1. Wypakuj paczkę, tak, żeby zawartość paczki była w folderze o nazwie "DSPack"
    2. Otwórz katalog, w którym zainstowałeś Delphi, i przejdź do podkatalogu "Lib". Przenieś do podkatalogu "Lib" katalog "DSPack"
    3. Otwórz katalog "DSPack" znajdujący się w katalogu "<katalog Delphi>\Lib".
    4. Przejdź do katalogu Packages, następnie uruchom "DirectX9_D6.dpk". Powinien uruchomić się Delphi z ciekawym oknem zawartości paczki. Klikamy "Compile"
    5. Teraz ważna sprawa przy której większość osób pytających ma problemy. W Delphi, klikamy na menu "Tools\Environment Options", w nowo-wyświetlonym oknie odnajdujemy na zakładce "Library" pole "Library path" i dopisujemy(!) do niego następujący ciąg:
      ;$(DELPHI)\Lib\DSPack\src\DirectX9;$(DELPHI)\Lib\DSPack\src\DSPack; Zamykamy okno, przechodzimy do naszego folderu z paczkami.
    6. Teraz kolej na kolejną paczkę o nazwie "DSPack_D6.dpk" - otwieramy ją i klikamy na "Compile"
    7. Instalujemy ostatnią z paczek (o nazwie "DSPackDesign_D6.dpk"), klikając nań i przyciskając "Install" w oknie które się pojawi.
    8. To wszystko!
  19. Jak łatwo odczytać nazwę, producenta, prędkość zainstalowanego procesora?
    Kładziemy na formularzu przycisk oraz komponent TMemo, w kodzie programu (klawisz F12) dodajemy słówko "Registry" do sekcji "uses". Klikamy dwukrotnie na przycisk i uzupełniamy nowo wygenerowaną procedurę następująco: procedure TForm1.Button1Click(Sender: TObject); var Reg : TRegistry; begin Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey('HARDWARE\DESCRIPTION\System\CentralProcessor\0',False); Memo1.Lines.Add('Nazwa: '+Reg.ReadString('ProcessorNameString')); Memo1.Lines.Add('Identyfikator: '+Reg.ReadString('Identifier')); Memo1.Lines.Add('Producent: '+Reg.ReadString('VendorIdentifier')); Memo1.Lines.Add('Prędkość: '+IntToStr(Reg.ReadInteger('~MHz'))); Reg.Free; end;
  20. Co zrobić by w ColorBoxsie nazwy kolorów były po Polsku?
    Jeśli nie chcesz mieć nazw typu "clBlue" czy "clRed" a wystarczą Ci nazwy "Blue" czy "Red" to w Inspektorze Obiektów (zaznacz wcześniej ColorBox) włącz właściwość Style/cbPrettyNames (przestaw na True) oraz włącz też właściwość Style/doCustomColor (też na True) - automatycznie wyświetla okienko z wyborem kolorów (wyłącz wszystkie inne właściwości z grupy Style - przestaw je na False). Po tej operacji pojawią się nazwy angielskie bez przedrostków "cl". Jeśli nazwy angielskie Ci nie pasują, a chciałbyś mieć nazwy typu "Niebieski", "Czerwony" to trzeba troszkę już pomyśleć. W każdej liście typu ListBox (ComboBox też jest taką listą) można dodać element do którego będzie przyporządkowana jakaś wartość liczbowa typu TObject. Może to być wskaźnik do jakiejś procedury, bądź rekordu (częściej). ColorBox zbudowany jest tak, że każdej pozycji odpowiada jakaś tam nazwa, a związana z nią wartość liczbowa jest po prostu kolorem rzutowanym na typ TObject. Można więc zrobić coś takiego (najlepiej zaraz przy tworzeniu Formy): ColorBox1.AddItem('Czarny',TObject($000000)); ColorBox1.AddItem('Biały',TObject($FFFFFF)); ColorBox1.AddItem('Niebieski',TObject($FF0000)); ColorBox1.AddItem('Zielony',TObject($00FF00)); ColorBox1.AddItem('Czerwony',TObject($0000FF)); Przy czym wartość liczbowa musi być typu TObject - jest to liczba 32-bitowa, taka jak TColor i taka jak wszystkie wskaźniki w procesorach i systemach 32-bitowych. Wartości kolorów zapisane są trójkami (BGR - czyli "Blue","Green","Red") w systemie hexadecymalnym. W ten sposób możesz dodać dowolny kolor. Jeśli powyższe jest zbyt skomplikowane, to możesz zamiast heksadecymalnych wartości liczbowych użyć predefiniowanych stałych jak clBlack, clWhite w następujący sposób: ColorBox1.AddItem('Czarny',TObject(clBlack)); ColorBox1.AddItem('Biały',TObject(clWhite)); ColorBox1.AddItem('Niebieski',TObject(clBlue)); ColorBox1.AddItem('Zielony',TObject(clGreen)); ColorBox1.AddItem('Czerwony',TObject(clRed));
  21. Czy przypisanie do zmiennej typu Byte wartości większej niż 255 skutkuje przepełnieniem?
    Okazuje się, że akurat w przypadku zmiennej typu Byte w Delphi, przypisanie wartości większej niż można przechować w typie Byte nie skutkuje przepełnieniem (nadpisaniem sąsiednich komórek pamięci, które nie były przeznaczone na naszą zmienną).
    Łatwo można to dowieść, deklarując tablicę, przepełniając np. element środkowy i wyświetlając jakie mają wartości elementy sąsiednie. Jeśli elementy sąsiednie mają wartość 0 (Delphi automatycznie inicjuje tablice) to znaczy, że nasza przepełniana komórka tablicy nie uległa przepełnieniu: var bajty : array[0..3] of byte; i : integer; begin for i:=0 To 513 Do bajty[2] := i; ShowMessage(IntToStr(bajty[1])); ShowMessage(IntToStr(bajty[3]));
  22. Jak zrobić okienko do zapisywania bitmapy w ilości kolorów zależnie od wybranej w okienku zapisu opcji?
    Połóż na formularzu przycisk (TButton) i komponent wyświetlający okienko do zapisywania obrazów (TSavePictureDialog). Zaznacz komponent SavePictureDialog1 i w Inspektorze Obiektów wypełnij pole Filter takim ciągiem: Plik BMP (monochromatyczny)|*.bmp|Plik BMP (kolorowy)|*.bmp Kilknij dwukrtonie na przycisk. Delphi powinien wygenerować procedurę zdarzeniową którą uzupełniasz następująco: var bmp : TBitmap; begin // Tworzymy bitmapę bmp := TBitmap.Create; // Ustalamy rozmiar bitmapy bmp.Width := 640; bmp.Height := 480; // Rysujemy elipsę bmp.Canvas.Ellipse(100,100,150,150); // Rysujemy bitmapę na formularzu Form1.Canvas.Draw(0,0,bmp); // Otwieranie okienka SavePictureDialog if SavePictureDialog1.Execute Then begin // USTALANIE ILOŚCI BITÓW NA PIKSEL (FORMATU KODOWANIA BARW) // ZALEŻNIE OD WYBRANEJ OPCJI W OKNIE SavePictureDialog case SavePictureDialog1.FilterIndex of 1 : bmp.PixelFormat := pf1bit; // konwersja do obrazu czarno-białego (monochromatycznego) 2 : bmp.PixelFormat := pf32bit; // konwersja do obrazu kolorowego end; // domyslny format to bmp.PixelFormat := pf24bit; bmp.SaveToFile(SavePictureDialog1.FileName+'.bmp'); // Zapis do pliku end; // Zwalnianie pamięci przydzielonej bitmapie FreeAndNil(bmp); Powyższy kod wygeneruje obraz przedstawiający małe kółko i zapisze go do pliku, konwertując go uprzednio do odpowiedniej (wybranej w oknie zapisu) ilości kolorów.

Łukasz "Lukas" Wyporek
lukas.home.page@gmail.com

Dexter
Czytelniku! Pomóż
rozruszać dyskusję!