Close Panel

3

Jan

2010

Bitcell.info

By DarkByte. Posted in Delphi, IT thingies, News | 1 Comment »

Un nou forum cu temă informatică, o nouă abordare. Sperăm să fie o abordare mai bună happy

Bitcell Forum

Vizitaţi-ne pe BitCell.info.

 

There are (a little) more that 11 years since, for the first time, I found Windows. I have had decided, after some ferm assurances that I would be helped if necessary, to try for the computer department in highschool, although I haven’t had seen a computer in my life before (this doesn’t count movies … and there they look good big grin)

Before the entrance exams in the summer of 1998 I was taken by my mother to her job where, at some offices, there were some computers, and the boss daughter used to play there often. Obviously, I went to see how a real computer looks like. Of course that, bright as I knew I was, I imagined that in two weeks I would learn everything that was possible about computers (I don’t really watch a lot of movies since that disillusionment straight face)..

 

17

Aug

2009

Oameni …

By DarkByte. Posted in Aberatii, De-ale vietii, Delphi | 13 Comments »

Aseară am revenit în Oradea, decis ca pe tren să-mi continui proiectele de programare care le am în curs.

În vederea acestui scop, mi-am lăsat laptopul la încărcat până în ultima clipă, apoi l-am pus în hibernare şi am plecat. Ajuns în gară, am hotărât să mă aşez în singurul locşor din tren unde există priză (de fapt, două alăturate … doar suntem europeni acum, nu?).

Am avut, totuşi, o mică surpriză, nu neapărat plăcută, când, după ce am urcat în tren, am remarcat că pe cele mai apropiate două locuri (de priză) erau două femei, una la vreo 35 de ani şi cealaltă undeva peste 50. Doar locul de dincolo de ele era gol, dar îmi displăcea profund ideea de a butona înghiontit de colegii de drum, cum mi s-a mai întâmplat

Mi-am luat inima în dinţi şi am rugat-o pe doamna mai tânără (cea care stătea chiar lângă priză), dacă se poate, să-mi doneze locul ei. Am contat pe faptul că nu avea telefon la încărcat şi nici nu părea să fie în stare să distingă un laptop închis de o cărămidă mai interesantă.

După ce a trebuit să repet de câteva ori întrebarea (s-a băgat şi doamna mai în vârstă în discuţie), a fost de acord să mă lase să-mi pun telefonul la încărcat acolo … când, într-un final, a înţeles că o rugam să se mute, a făcut o mutră mai acră, dar s-a mutat, lăsându-şi totuşi bagajul să-i ţină companie trollerului meu.

Nu a uitat, atunci când s-a aşezat pe noul loc, să arunce o ultimă replică mai veninoasă: “Ştii, nu e frumos să ridici femeile !”. Da, ştiu, doar pe piedestal …

Chiar m-a blocat niţel … probabil că s-a şi văzut pe faţa mea, pentru că nu a mai adăugat nimic.

Tanti nu avea nici un folos pentru amărâta aia de priză, iar în acel tren doar acolo există vreo priză. Cu ce-am deranjat-o atât de tare că am rugat-o să se mute în cealaltă parte a femeii în vârstă, ţinând cont de faptul că am rugat-o frumos?

Cireaşa de pe tort a venit un pic mai încolo, totuşi … la prima staţie ambele femei au coborât … asta chiar m-a lăsat mască. Pentru 10 minute de călătorie s-a gândit să-mi arunce remarca aia? Sau doar pentru că era de la ţară?

Cred că oamenii nu se simt bine dacă nu încearcă să facă pe alţi oameni să se simtă prost … just for the fun of it.

 

15

Aug

2009

Calculator de bioritm

By DarkByte. Posted in Delphi, IT thingies | 2 Comments »

Destul de recent, am primit linkuri pe site-uri care-ți calculau bioritmul și afișau graficele și mi s-a părut destul de interesant, așa că … m-am apucat să-mi fac un program care să-mi afișeze bioritmul, fără să fie nevoie să intru pe vreun site sau să am măcar conexiune la Internet.

Cu toate acestea, ce trebuie să ştiţi este că aceste cicluri bioritmice nu sunt dovedite ştiinţific, ba chiar, mai curând, infirmate. Pentru detalii, vedeţi ce zice Wikipedia.

Acestea fiind spuse, să trecem la partea tehnică și informatică din spatele acestui program.

Probabil că știți că pentru a desena o sinusoidală pe calculator, calculezi o serie de puncte, care le unești prin linii. O treabă foarte ușoară în Delphi. Ceea ce probabil că nu știți e faptul că există o funcție în Delphi, care unește o serie de puncte prin linii mult mai rapid decât dacă ai face o buclă, desenând liniile una câte una. Funcția se numește PolyLine (o puteți căuta în Help).

Mai exact, un cod de forma

begin
   MoveTo(0, F(0));
   for i := 1 to 100 do
      LineTo(i, F(i));
end;

ar putea fi optimizat cu codul următor:

var lPoints: array of TPoint;
begin
   SetLength(lPoints, 101 );
 
   for i := 0 to 100 do
      with lPoints[i] do
      begin
         X := i;
         Y := F(i);
      end;
 
   Polyline(lPoints);
end;

În afară de acest lucru, restul codului este ușor de înțeles, fiind și parțial comentat. Sursa este scrisă în Delphi 7, dar probabil că va compila și cu alte versiuni de Delphi (mai vechi sau mai noi).

Download : Sursa :: Executabil :: Screenshot

Comentarii, bug-uri, sugestii : binevenite. Also, partea grafică a programului m-a interesat doar din punctul de vedere al graficelor, deci … știu că poate fi îmbunătățit designul.

 

20

Jul

2008

Window Spy

By DarkByte. Posted in Delphi | 8 Comments »

Win 32 APIProbabil că ştiţi că în Windows totul se bazează pe ferestre … era destul de evident, nu ?

Să vedem cum am putea afla câte ceva legat de ferestrele vizibile şi cum am putea să le ascundem, să le dezactivăm, etc, totul din Borland Delphi, folosind funcţii API.Borland Delphi 7

Pentru început, să vedem cum aflăm ce fereastră avem sub cursorul de mouse.

Pentru asta ne trebuie să ştim poziţia cursorului, care se poate afla folosind funcţia GetCursorPos, din care putem afla handle-ul ferestrei de sub cursor, folosind funcţia WindowFromPointSă vedem nişte cod.

var hWindow  : Longint;
    P : TPoint;
  ...
  GetCursorPos(P);
 
  hWindow := WindowFromPoint(P);

Destul de simplu, nu ? În variabila hWindow avem acum handle-ul care ne interesează.
Pentru a “vedea” în timp real ce fereastra e sub cursor, punem codul acesta într-un TTimer.

Să vedem cum afişăm informaţiile găsite, cum ar fi titlul ferestrei, clasa ferestrei (adică tipul componentei) şi handle-ul asociat părintelui ei, din TTimer. Pentru asta avem nevoie (în cazul acesta) de patru TEdit-uri.

procedure TForm1.Timer1Timer(Sender: TObject);
var hWindow  : Longint;
    P : TPoint;
    buff : Array[0..255] of char;
begin
  GetCursorPos(P);
 
  hWindow := WindowFromPoint(P);
  Edit2.Text := '$' + IntToHex(hWindow, 8);
 
  GetWindowText(StrToInt(Edit2.Text), Buff, 255);
  Edit1.Text := Buff;
 
  GetClassName(StrToInt(Edit2.Text), Buff, 255);
  Edit3.Text := Buff;
 
  If GetParent(StrToInt(Edit2.Text)) > 0
    then Edit4.Text := '$' + IntToHex(GetParent(StrToInt(Edit2.Text)), 8)
    else Edit4.Text := 'None';
end;

GetWindowText returnează titlul ferestrei (sau textul din fereastră, dacă e vorba de un TEdit), GetClassName returnează tipul componentei, iar GetParent handle-ul părintelui. Simplu, nu ? happy

Păcat că momentan tot ce aflăm sunt lucruri destul de puţin importante şi deloc atrăgătoare. Nişte numere şi ceva text care oricum se vedea şi fără un asemenea program. Să încercăm ceva mai atrăgător.

Pentru început vom ascunde / reafişa fereastra, apelând funcţia ShowWindow, care are nevoie de doi parametri: handle-ul ferestrei şi un parametru care specifică dacă vrem să afişăm sau să ascundem fereastra.

Afişare fereastră:

ShowWindow(wHandle, SW_SHOW);

Ascundere fereastră:

ShowWindow(wHandle, SW_HIDE);

Alt lucru care-l putem face : vom seta ca fereastra selectată să devină fereastră de top-level şi înapoi. Pentru acest lucru vom folosi funcţia SetWindowPos pentru a ne defini o procedură apelabilă cu un parametru de tip Boolean care să ştie modifica stilul ferestrei în ambele moduri, al doilea parametru fiind handle-ul ferestrei care vrem s-o modificăm.

procedure SetTop(Top : Boolean; Handle : HWnd);
Begin
  If Top
    Then
      Begin
        SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
                     SWP_SHOWWINDOW + SWP_NOMOVE + SWP_NOSIZE);
        SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0,
                     SWP_SHOWWINDOW + SWP_NOMOVE + SWP_NOSIZE);
      End
    Else SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0,
                      SWP_SHOWWINDOW + SWP_NOMOVE + SWP_NOSIZE);
End;

Acum nu mai avem decât să apelăm procedura asta din butonul corespunzător.

Ştiind handle-ul ferestrei, o putem şi activa / dezactiva folosind EnableWindow, care necesită specificarea handle-ului ferestrei şi un parametru logic care determină activarea / dezactivarea ei.

Codul pentru cele şase butoane de până acum:

procedure TForm1.bShowClick(Sender: TObject);
begin
  hWindow := HexToInt(Copy(Edit2.Text, 2, Length(Edit2.Text) - 1));
  ShowWindow(hWindow, SW_SHOW);
end;
 
procedure TForm1.bHideClick(Sender: TObject);
begin
  hWindow := HexToInt(Copy(Edit2.Text, 2, Length(Edit2.Text) - 1));
  ShowWindow(hWindow, SW_HIDE);
end;
 
procedure TForm1.bTopClick(Sender: TObject);
begin
  hWindow := HexToInt(Copy(Edit2.Text, 2, Length(Edit2.Text) - 1));
  SetTop(True, hWindow);
end;
 
procedure TForm1.bPotClick(Sender: TObject);
begin
  hWindow := HexToInt(Copy(Edit2.Text, 2, Length(Edit2.Text) - 1));
  SetTop(False, hWindow);
end;
 
procedure TForm1.bEnableClick(Sender: TObject);
begin
  hWindow := HexToInt(Copy(Edit2.Text, 2, Length(Edit2.Text) - 1));
  EnableWindow(hWindow, True);
end;
 
procedure TForm1.bDisableClick(Sender: TObject);
begin
  hWindow := HexToInt(Copy(Edit2.Text, 2, Length(Edit2.Text) - 1));
  EnableWindow(hWindow, False);
end;

Probabil că aţi remarcat linia

hWindow := HexToInt(Copy(Edit2.Text, 2, Length(Edit2.Text) - 1));

, despre care nu am scos nici un cuvânt până acum. Este inversa funcţiei IntToHex din Delphi, şi este definită mai jos.

function HexToInt(S : String): Longint;
var B : Byte;
    C : Char;
Begin
  Result := 0;
  s := UpperCase(s);
  For B := 1 To Length(s) Do
    Begin
      Result := Result * 16;
      c := S[B];
      Case c Of
        '0'..'9': Inc(Result, Ord(c) - Ord('0'));
        'A'..'F': Inc(Result, Ord(c) - Ord('A') + 10);
        Else
          Begin
            Result := 0;
            Exit;
          End;
      End;
    End;
End;

Puteam folosi variabila hWindow ca variabilă globală şi atunci scăpam de nevoia folosirii acestei funcţii, nu ? Dar ce se întâmpla dacă la utilizarea programului se voia reafişarea unei ferestre căreia îi ştim handle-ul ? În acest fel tot ce avem de făcut este editarea celei de-a doua căsuţe text cu handle-ul respectiv şi putem face orice, altfel putând lucra doar cu ferestrele vizibile pe ecran.

Cam acesta ar fi codul necesar pentru o mini-aplicaţie de lucru cu ferestrele … dar stai … e o problemă … dacă verificarea ferestrei de sub mouse se face în timp real, înseamnă că … da, dacă selectez butonul de “ascundere fereastră”, îmi va ascunde tocmai respectivul buton. Damn, nu e bine.

Trebuie să programăm o metodă de a opri scanarea ferestrelor în timp real, o dată ce am selectat fereastra cu care vrem să lucrăm, fără să mişcăm mouse-ul. Pentru asta ne vom defini o combinaţie de taste globală, folosind funcţia RegisterHotKey, care primeşte patru parametri: handle-ul ferestrei căreia să-i trimită mesaj în caz că s-a apăsat combinaţia noastră de taste, un identificator pentru combinaţie, definit de noi, şi combinaţia de taste, definită prin doi parametri – primul, care defineşte dacă tastele CTRL, ALT, SHIFT sau WIN sunt apăsate, şi al doilea, care defineşte o tastă normală (cum ar fi “R”winking. Apelul funcţiei, pentru a ne defini combinaţia CTRL + F8, este :

const StopKey = 100000;
  ...
  RegisterHotKey(Handle, StopKey, MOD_CONTROL, VK_F8);

Această linie trebuie apelată chiar la începutul rulării programului, în FormCreate.
Atenţie : StopKey este o constantă ce trebuie definită global, înaintea secţiunii implementation.

Pentru a fi anunţaţi când este apăsată combinaţia noastră de taste ne vom defini o procedură care să primească mesajul trimis de sistem, interceptând mesajul WM_HOTKEY.

type
  TForm1 = class(TForm)
  ...
  private
    { Private declarations }
    procedure WMHotKey(var Message: TMessage); message WM_HOTKEY;
 ...

Codul procedurii :

procedure TForm1.WMHotKey(var Message: TMessage);
begin
  If Message.WParam = StopKey
    Then Timer1.Enabled := not Timer1.Enabled;
end;

Practic, la fiecare apăsare a combinaţiei, TTimer-ul nostru se va opri / reporni. Pentru a nu lăsa mizerie după rularea programului, va trebui să distrugem această combinaţie de taste la oprire. Pentru acest lucru, în FormCloseQuery vom apela :

  UnregisterHotKey(Handle, StopKey);

Cam asta ar fi tot codul.

Pentru a nu vă pune să lucraţi cu copy / paste şi să vă faceţi griji de componente şi asignări de evenimente, aveţi mai jos sursele şi executabilul arhivate.

Download : Sursa :: Executabil