[API WINDOWS] HORLOGE DIGITALE TRANSPARENTE SUR LE BUREAU

DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015 - 25 juil. 2004 à 17:59
cs_clandestino Messages postés 16 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 11 novembre 2004 - 7 sept. 2004 à 20:34
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/24863-api-windows-horloge-digitale-transparente-sur-le-bureau

cs_clandestino Messages postés 16 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 11 novembre 2004
7 sept. 2004 à 20:34
C'est de la programmation utilisant l'api windows... donc ça marche sous....
Nerolph Messages postés 58 Date d'inscription vendredi 24 octobre 2003 Statut Membre Dernière intervention 4 septembre 2012
7 sept. 2004 à 20:23
Et ça marche sous quel OS ?
cs_clandestino Messages postés 16 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 11 novembre 2004
28 juil. 2004 à 11:01
great :)
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
27 juil. 2004 à 17:15
pour le constante,sendmessage(hwindow,274,61458,0) c'est simplement
parce que j'ai supprimer dans un autre code
uses windows;

ce qui impliquait de ne plus utiliser les const de ce fichier
et de réimporter les fonction gdi.dll user32.dll et autres
et comme le résultat est le même (ce qui prouve encore une fois la très grande efficacité du compilateur),d'importer les type,enfin tout ce travail environ 2 heure à chercher ,copier,coller, transposer ,remanipuler les record pour en faire de type params semblabe acceptable etc...

le compilateur étant ce qu'il est ,une constante ne doit donc pas être supprimer,puisque nous pouvons en debug time en connaître la signification, ici j'avais précalculé (Ws_machin or Ws_overlapped)or ws_visible)ce qui donnait un cardinal ...il n'y a donc aucun gain d'espace dans ce cas ,la valeur étant affecté directement .Difficile en effet de voir où une grande ligne de code n'occupera qu'en fait un byte ? peut-être pas tant que ça ...j'ai télécharger dernièrement un soft qui lis les exe ou les dll et qui les recompile ,permettant de voir les exportations,les entrées,mais on en revient à la base de l'asm.Ce soft n'est pas gratuit (démo 30 jours)il s'applelle PE Explorer.

Pour nous nous avons accès au code asm en utilisant la commande voir/fenêtres de débogage/cpu

donc à la lecture du code
procedure affichage;
je crois qu'ici il y aurait moyen de simplifier encore ,
procedure affichage;
var
points:packed array [0..5] of tpoint;
R1, R2 : Cardinal;
led:Byte;
Procedure point(aa:byte;bb:byte;cc:byte);
begin
points[aa].x:=bb+4;
points[aa].y:=cc+30;
End;
Procedure Setpoint(num,led,a1,a2,a3,a4,a5,a6:byte);
begin
Point( 0, valeur[num,led,0] ,a1 );
Point( 1, valeur[num,led,1] ,a2 );
Point( 2, valeur[num,led,2] ,a3 );
Point( 3, valeur[num,led,3] ,a4 );
Point( 4, valeur[num,led,4] ,a5 );
Point( 5, valeur[num,led,5] ,a6 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);
end;
begin
R1 := CreateRectRgn(0,0,0,0);
for led :=1 to 4 do begin
if chiffre[led].A = 1 then Setpoint(1,led,4,1,1,4,7,7);
if chiffre[led].B = 1 then Setpoint(2,led,5,8,30,33,30,8);
if chiffre[led].C = 1 then Setpoint(3,led,5,8,30,33,30,8);
if chiffre[led].D = 1 then Setpoint(1,led,34,31,31,34,37,37);
if chiffre[led].E = 1 then Setpoint(2,led,35,38,60,63,60,38);
if chiffre[led].F = 1 then Setpoint(3,led,35,38,60,63,60,38);
if chiffre[led].G = 1 then Setpoint(1,led,64,61,61,64,67,67);
end;

if clignot=1 then begin
Point( 0, 86 ,19 );
Point( 1, 92 ,19 );
Point( 2, 92 ,24 );
Point( 3, 86 ,24 );
R2:=CreatePolygonRgn(Points[0],4,2);
CombineRgn(R1,R1,R2,3);
Point( 0, 86 ,43 );
Point( 1, 92 ,43 );
Point( 2, 92 ,48 );
Point( 3, 86 ,48 );
R2:=CreatePolygonRgn(Points[0],4,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
SetWindowRgn(hwindow,R1,TRUE);
deleteobject(R1);
end;

quelques octets de gagner mais bon !!!
cs_clandestino Messages postés 16 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 11 novembre 2004
27 juil. 2004 à 09:32
Le portage de ta source sous freepascal m'a obligé à quelques modifications mineures, et notemment la fonction miseajour...

Je n'avais pas réussi à la definir directement dans la création du timer, ce qui m'obligeait à gerer un evènement WM_TIMER..

En effet, contrairement à Delphi (plus tolérent !!) freepascal refuse de compiler la ligne
Settimer(hwindow,1,500,@miseajour);

si miseajour n'a pas une structure Timerproc stricte
j'ai du donc modifier ainsi
miseajour(a:HWND; b:ulong; c:ulong, d:ulong);

et faire mes appels de la manière suivante

miseajour(hwindow,0,0,0);

Merci, c'est grace à toi que je me suis repenché sur le problème et que j'ai compris la solution...

Clan
cs_clandestino Messages postés 16 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 11 novembre 2004
27 juil. 2004 à 08:58
J'aime lire du code, c'est la meilleure façon de progresser :
voir face à un meme problème, les solutions différentes envisagées par d'autres...
j'aime le ord(bidule)-48, c'est vraiment un gain de code...
l'utilisation des tableaux mo et array est sans conteste plus efficace aussi...
le pchar ne fonctionnant pas sous freepascal je ne l'utilise plus @ma_string[1]+#0 ce qui m'oblige souvent à passer par une string temporaire de stockage ne pouvant avec cette formule me permettre des additions de caratères du style :
''+toto[1]+toto[2]+':'+toto[3]+toto[4]+#0
l'utilisation des valeurs exactes au lieu des textes generiques (par exemple sendmessage(hwindow,274,61458,0) )pour les constantes systemes est elle une habitude ou participe-t'elle à la taille reduite de l'executable final?

Un grand merci...

Clan
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
26 juil. 2004 à 21:59
Bon alors j'y inclus le code ,évidemment j'ai modifier quelques truc pour me comprendre,et tout le crédit te reviens après tout j'ai simplement tenté de simplifié.

Program time;
uses windows;
type string4=string[4];
Type Fnumero = ^Tnumero;
numeros = packed record
A : byte;// ____a___
B : byte;// | |
C : byte;// b| |c
D : byte;// |____d___|
E : byte;// | |
F : byte;// e| |f
G : byte;// |____g___|
end;
Tnumero = numeros;
Var
WinClass: TWndClass;
Inst: Cardinal;
hWindow: Cardinal;
TheMessage: tagMSG;
maintenant : Tsystemtime;
toto : string4;
clignot : byte;
chiffre : array[1..4] of Tnumero;
const
mo:packed array[0..9,0..6]of byte=((1,1,1,0,1,1,1),(0,0,1,0,0,1,0),(1,0,1,1,1,0,1),(1,0,1,1,0,1,1),(0,1,1,1,0,1,0),(1,1,0,1,0,1,1),(1,1,0,1,1,1,1),(1,0,1,0,0,1,0),(1,1,1,1,1,1,1),(1,1,1,1,0,1,1));
valeur:packed array[1..3,1..4,0..5]of byte=
(((5,8,30,33,30,8),(48,51,73,76,73,51),(102,105,127,130,127,105),(145,148,170,173,170,148)),
((4,7,7,4,1,1),(47,50,50,47,44,44),(101,104,104,101,98,98),(144,147,147,144,141,141)),
((34,37,37,34,31,31),(77,80,80,77,74,74),(131,134,134,131,128,128),(174,177,177,174,171,171)));
function heure :String4;
begin
getlocaltime(maintenant);
heure:=char((maintenant.wHour div 10) +48)+char(maintenant.wHour mod 10+48)+char((maintenant.wMinute div 10) +48)+char(maintenant.wMinute mod 10+48);
end;
procedure affichage;
var
points:packed array [0..5] of tpoint;
R1, R2 : Cardinal;
led:Byte;
Procedure point(aa:byte;bb:byte;cc:byte);
begin
points[aa].x:=bb+4;
points[aa].y:=cc+30;
End;
begin
R1 := CreateRectRgn(0,0,0,0);
for led :=1 to 4 do begin
if chiffre[led].A = 1 then begin
Point( 0, valeur[1,led,0] ,4 );
Point( 1, valeur[1,led,1] ,1 );
Point( 2, valeur[1,led,2] ,1 );
Point( 3, valeur[1,led,3] ,4 );
Point( 4, valeur[1,led,4] ,7 );
Point( 5, valeur[1,led,5] ,7 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
if chiffre[led].B = 1 then begin
Point( 0, valeur[2,led,0] ,5 );
Point( 1, valeur[2,led,1] ,8 );
Point( 2, valeur[2,led,2] ,30 );
Point( 3, valeur[2,led,3] ,33 );
Point( 4, valeur[2,led,4] ,30);
Point( 5, valeur[2,led,5] ,8 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
if chiffre[led].C = 1 then begin
Point( 0, valeur[3,led,0] ,5 );
Point( 1, valeur[3,led,1] ,8 );
Point( 2, valeur[3,led,2] ,30 );
Point( 3, valeur[3,led,3] ,33 );
Point( 4, valeur[3,led,4] ,30);
Point( 5, valeur[3,led,5] ,8 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
if chiffre[led].D = 1 then begin
Point( 0, valeur[1,led,0] ,34 );
Point( 1, valeur[1,led,1] ,31 );
Point( 2, valeur[1,led,2] ,31 );
Point( 3, valeur[1,led,3] ,34 );
Point( 4, valeur[1,led,4] ,37);
Point( 5, valeur[1,led,5] ,37 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
if chiffre[led].E = 1 then begin
Point( 0, valeur[2,led,0] ,35 );
Point( 1, valeur[2,led,1] ,38 );
Point( 2, valeur[2,led,2] ,60 );
Point( 3, valeur[2,led,3] ,63 );
Point( 4, valeur[2,led,4] ,60);
Point( 5, valeur[2,led,5] ,38 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
if chiffre[led].F = 1 then begin
Point( 0, valeur[3,led,0] ,35 );
Point( 1, valeur[3,led,1] ,38 );
Point( 2, valeur[3,led,2] ,60 );
Point( 3, valeur[3,led,3] ,63 );
Point( 4, valeur[3,led,4] ,60);
Point( 5, valeur[3,led,5] ,38 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
if chiffre[led].G = 1 then begin
Point( 0, valeur[1,led,0] ,64 );
Point( 1, valeur[1,led,1] ,61 );
Point( 2, valeur[1,led,2] ,61 );
Point( 3, valeur[1,led,3] ,64 );
Point( 4, valeur[1,led,4] ,67);
Point( 5, valeur[1,led,5] ,67 );
R2:=CreatePolygonRgn(Points[0],6,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
end;

if clignot=1 then begin
Point( 0, 86 ,19 );
Point( 1, 92 ,19 );
Point( 2, 92 ,24 );
Point( 3, 86 ,24 );
R2:=CreatePolygonRgn(Points[0],4,2);
CombineRgn(R1,R1,R2,3);
Point( 0, 86 ,43 );
Point( 1, 92 ,43 );
Point( 2, 92 ,48 );
Point( 3, 86 ,48 );
R2:=CreatePolygonRgn(Points[0],4,2);
CombineRgn(R1,R1,R2,3);
deleteobject(R2);end;
SetWindowRgn(hwindow,R1,TRUE);
deleteobject(R1);
end;

procedure SetEtat(i,j:Byte);
begin
chiffre[j].A := mo[ord(toto[i])-48,0];
chiffre[j].B := mo[ord(toto[i])-48,1];
chiffre[j].C := mo[ord(toto[i])-48,2];
chiffre[j].D := mo[ord(toto[i])-48,3];
chiffre[j].E := mo[ord(toto[i])-48,4];
chiffre[j].F := mo[ord(toto[i])-48,5];
chiffre[j].G := mo[ord(toto[i])-48,6];
end;

procedure miseajour;
begin
toto:=heure;
setwindowtext(hwindow,PChar(''+toto[1]+toto[2]+':'+toto[3]+toto[4]+#0));
SetEtat(1,1);
SetEtat(2,2);
SetEtat(3,3);
SetEtat(4,4);
if(clignot=1)then clignot:=0 else clignot:=1 ;
affichage;
UpdateWindow(hWindow);
end;

function WindowProc(hWindow: cardinal; Message,wParam,lParam: Integer): Integer; stdcall;
begin
WindowProc := 0;
case Message of
1 :Settimer(hwindow,1,500,@miseajour);
513:sendmessage(hwindow,274,61458,0);
2:begin killtimer(hwindow,1);
postquitmessage(0);end;else
WindowProc := DefWindowProc(hWindow, Message, wParam, lParam);end;
end;
begin
Inst := hInstance;with WinClass do begin
style := 3;
lpfnWndProc := @WindowProc;
hInstance := Inst;
hbrBackground := createsolidbrush( RGB(255,255,0) );
lpszClassname := 'MyWindowClass';
hCursor := LoadCursor(0, PAnsiChar(32512) );end;
RegisterClass(WinClass);
hWindow := CreateWindowEx(8,'MyWindowClass','Timer',281870336,Getsystemmetrics(0)-200,Getsystemmetrics(1)-140,200,110,0,0,Inst,nil);
miseajour;
while GetMessage(TheMessage,0,0,0) do begin
if not IsDialogMessage(hWindow,TheMessage)then begin
TranslateMessage(TheMessage);
DispatchMessage(TheMessage);end;end;
end.
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
26 juil. 2004 à 19:04
Allez, je te mets 8/10!
J' ai juste jeter un oeil mais j' ai vu pleins de trucs instructifs ...
Je voudrais faire (peut-être en 2005 si j' ai le temps) un composant type affichage digital de chiffres et de lettres comme dans ton exemple mais aussi avec des petits points qui forme les lettres... Un truc machin genre TLabel, quoi!!!
cs_clandestino Messages postés 16 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 11 novembre 2004
26 juil. 2004 à 12:19
j'aimerai bien connaitre tes modifs :)
Si tu veux bien m'en parler ....

je viens de me rendre compte que petit à petit cette horloge occuppe de la mémoire...
J'ai omis à chaque affichage de detruire les regions crées...
un delete objet(r2) à la suite de chaque combinergn dans la procedure 'affichage' et un deleteobject(r1) en debut de cette procedure corrigent cette fuite...

see ya
Clan
yvemoreau Messages postés 308 Date d'inscription mardi 11 juin 2002 Statut Membre Dernière intervention 26 septembre 2008
26 juil. 2004 à 04:18
Bonjour, c'est bien !!!

j'ai modifier quelques truc puis j'arrive à 18k.

en trichant un peu 7,5 k

C'était un défi.
cs_clandestino Messages postés 16 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 11 novembre 2004
25 juil. 2004 à 18:31
Sympa ton code...

Le mien est bien plus long :(... car j'essaie de ne pas utiliser de composant tout prêt ... C'est une façon différente de coder qui oblige à réécrire des trucs simples...
L'avantage principal, après la taille du programme généré, est que celà me permet d'apprendre enormément...
Utiliser un timer windows, réécrire inttostr et strtoint...

Ici le challenge était double :
Ne pas utiliser de composant (puisqu'au départ c'est un code freepascal) et afficher une police LCD...

Le résultat est bourré de répétitions et est surement perfectible... N'hésitez pas à me signaler mes maladresses...

Clan
DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
25 juil. 2004 à 17:59
pas mal,

j'avais créé aussi une horloge transparente, si tu veux voir le code (un peu différent) :

http://www.phidels.com/php/index.php3?page=../php/pagetelechargementzip.php3&id=461

;)
Rejoignez-nous