salut,
je suis entraine d'apprendre comment faire un economiseur d'ecran sous windows XP avec langage c.
qlqun peut me montrer la skeleton d'un tel programme avec des petites commentaires sur chaque methode,
salut,
je suis entraine d'apprendre comment faire un economiseur d'ecran sous windows XP avec langage c.
qlqun peut me montrer la skeleton d'un tel programme avec des petites commentaires sur chaque methode,
merci, mais moi je veux le faire sans utiliser la librairie screen saver juste par un code en c cas cette librairie demande de creer des autres fichier que la classe en c,
merci de nouveau
bonjour,
j ai un collegue qui s'amuse a en faire en "Glut", c'est ptet sortir le marteau piqueur pour accrocher un tableau mais ca l'occupe vachement et le resultat est tres beau, qu'est ce qu'on s'amuse au boulot![]()
Bonjour,
qlqn peut me montrer un code example pour un economiseur simple qui n'utilise pas la librairie screensaver, j'ai essaye tte la semaine mais j'arrive pas a faire qlq chose![]()
Bah, quand on programme en C, on a besoin d'un fichier source (contenant le code du programme), de fichiers d'en-tête (qui contiennent la déclaration des fonctions qu'on va utiliser), de fichiers précompilés (.lib) contenant le code des fonctions qu'on va utiliser, du son à jouer, des images à afficher, etc. bref, que des fichiers. Ca n'a rien à voir avec scrnsave.lib donc si c'est la raison pour laquelle tu fuis cette bibliothèque, tu fuis plutôt le C. J'ai fait un petit screen saver (avec scrnsave.lib) histoire de te montrer que ça n'a rien de compliqué (en tout as, par rapport aux écrans de veille DX, ...).
Cet écran de veille dessine à chaque seconde, et de manière aléatoire, un petit rectangle blanc. Voici le code :
Tu dois : te lier avec scrnsave.lib (peut-être aussi avec comctl32.lib selon la version de ton compilateur), compiler sans UNICODE et exporter les fonctions ScreenSaverProc et ScreenSaverConfigureDialog à l'aide d'un fichier .def (tiens, un autre fichier). Si tu ne sais pas ce que c'est qu'un def file, tu dois étudier en profondeur les techniques de génération de DLLs. Ici t'as juste besoin d'un tout petit fichier def pour pouvoir exporter ces fonctions, je t'en fourni un exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 #include <windows.h> #include <scrnsave.h> #include <stdlib.h> #include <time.h> static int runif(int a, int b); static void rand_rect(RECT * p1, const RECT * p2); LONG WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hDC; static RECT screen; static UINT_PTR Timer; RECT r; switch(message) { case WM_CREATE: hDC = GetDC(hwnd); screen.right = GetSystemMetrics(SM_CXSCREEN); screen.bottom = GetSystemMetrics(SM_CYSCREEN); srand((unsigned)time(NULL)); Timer = SetTimer(hwnd, 1, 1000, NULL); /* Timer activé toutes les 1000 ms (1 s) */ break; case WM_TIMER: FillRect(hDC, &screen, GetStockObject(BLACK_BRUSH)); /* Efface l'écran */ rand_rect(&r, &screen); /* Calcule un rectangle aléatoire qui peut rentrer dans screen */ FillRect(hDC, &r, GetStockObject(WHITE_BRUSH)); /* Dessine le rectangle */ break; case WM_DESTROY: KillTimer(hwnd, Timer); ReleaseDC(hwnd, hDC); break; default: return (LONG)DefScreenSaverProc(hwnd, message, wParam, lParam); } return 0; } BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { /* Ne nous intéresse pas pour le moment */ return TRUE; } BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { /* Ne nous intéresse pas pour le moment */ return TRUE; } int runif(int a, int b) /* Retourne un nombre aléatoire (loi uniforme) compris entre a et b */ { return (int)(a + (((double)(b - a))/RAND_MAX) * rand() + 0.5); } void rand_rect(RECT * p1, const RECT * p2) { p1->left = runif(0, p2->right - 200); p1->top = runif(0, p2->bottom - 200); p1->right = p1->left + runif(100, 200); p1->bottom = p1->top+ runif(100, 200); }
Et voilà, tu n'as plus qu'à compiler ton projet, renommer l'exe en .scr (sauf si t'as déjà reglé cela dans les options du projet ...), et le tester. Si t'es satisfait, tu le copies enfin dans le répertoire system32 pour qu'il soit reconnu par Windows. Et si en plus tu connais un peu d'OpenGL, tu peux remplacer les rectangles par des cubes, avec des couleurs, du brouillard, des lumières, etc.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 EXPORTS ScreenSaverProc ScreenSaverConfigureDialog
En espérant t'avoir aidé.
salut Melem,
J'ai essayer ton code, il marchemerci.
J'ai essayer d'integrer OpenGl a l'écran de veille.
Je te passe pas les diverses fonctions OpenGl, elles sont disponibles là mais hélàs je n'obtiens qu'un ecran noir, normalement, j'ai pour l'instant programmer que le repère trigonomique...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 LONG WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_CREATE: hDC = GetDC(hwnd); SetupPixelFormat(hDC); RC = wglCreateContext(hDC); wglMakeCurrent(hDC, RC); // screen.right = // screen.bottom = ; srand((unsigned)time(NULL)); // InitGL(); // Reshape(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); Timer = SetTimer(hwnd, 1, 1000, NULL); /* Timer activé toutes les 1000 ms (1 s) */ break; case WM_TIMER: // FillRect(hDC, &screen, GetStockObject(BLACK_BRUSH)); /* Efface l'écran */ // rand_rect(&r, &screen); /* Calcule un rectangle aléatoire qui peut rentrer dans screen */ // FillRect(hDC, &r, GetStockObject(WHITE_BRUSH)); /* Dessine le rectangle */ Draw(); break; case WM_DESTROY: KillTimer(hwnd, Timer); ReleaseDC(hwnd, hDC); break; default: return (LONG)DefScreenSaverProc(hwnd, message, wParam, lParam); } return 0; } BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { /* Ne nous intéresse pas pour le moment */ return TRUE; } BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { /* Ne nous intéresse pas pour le moment */ return TRUE; }
Si tu veux une fonction en particulier....
Merci de ton aide.
Flo
Tu n'as pas correctement initialisé ta vue. En outre même si ça n'a rien à voir, il faut libérer le RC dans WM_DESTROY. Voici le même écran de veille en OpenGL, avec une vue 2D (projection parallèle). Mais avant cela, quelques points à connaître :
- J'ai remplacé rand_rect par gl_rand_rect car le système de coordonnées utilisé en OpenGL (repère direct) est différent de celui utilisé par défaut sous Windows (MM_TEXT).
- runif a été modifié de façon à traiter convenablement les nombres négatifs.
- J'ai utilisé la fonction SetupPixelFormat du lien que tu m'as donné mais j'ai supprimé le double buffering (complètement inutile pour une animation de 1 image/seconde), ce qui explique le glFlush à la fin des dessins. Sinon ben t'as qu'à remplacer glFlush par SwapBuffers(hDC).
Et voilà. Tu peux maintenant tranquillement faire des écrans de veille 3D.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 #include <windows.h> #include <scrnsave.h> #include <gl/gl.h> #include <stdlib.h> #include <time.h> typedef struct { int x1, y1, x2, y2; } GLRECT; #define XMIN -10 #define XMAX 10 #define YMIN -10 #define YMAX 10 #define RECT_MIN 2 #define RECT_MAX 4 static int runif(int a, int b); static void gl_rand_rect(GLRECT * p); void SetupPixelFormat(HDC hDC); LONG WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hDC; static HGLRC hRC; static UINT_PTR Timer; GLRECT r; switch(message) { case WM_CREATE: /* Initialiser OpenGL */ hDC = GetDC(hwnd); SetupPixelFormat(hDC); hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); glClearColor(0, 0, 0, 0); /* Initialiser l'animation */ srand((unsigned)time(NULL)); Timer = SetTimer(hwnd, 1, 1000, NULL); break; case WM_SIZE: glViewport(0, 0, LOWORD(lParam), HIWORD(lParam)); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(XMIN, XMAX, YMIN, YMAX, -1, 1); break; case WM_TIMER: gl_rand_rect(&r); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); glVertex2i(r.x1, r.y1); glVertex2i(r.x2, r.y1); glVertex2i(r.x2, r.y2); glVertex2i(r.x1, r.y2); glEnd(); glFlush(); break; case WM_DESTROY: KillTimer(hwnd, Timer); wglDeleteContext(hRC); ReleaseDC(hwnd, hDC); break; default: return (LONG)DefScreenSaverProc(hwnd, message, wParam, lParam); } return 0; } BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { return TRUE; } BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { return TRUE; } int runif(int a, int b) { double x = a + (((double)(b - a))/RAND_MAX) * rand(); return (int)(x >= 0 ? x + 0.5 : x - 0.5); } void gl_rand_rect(GLRECT * p) { p->x1 = runif(XMIN, XMAX - RECT_MAX); p->y1 = runif(YMIN + RECT_MAX, YMAX); p->x2 = p->x1 + runif(RECT_MIN, RECT_MAX); p->y2 = p->y1 - runif(RECT_MIN, RECT_MAX); }
Ben tout d'abord tu crées un projet d'application Windows (Windows Application, pas Windows Console Application), ensuite dans les options de ton projet (Project > Settings), tu vas dans les options du Linkeur et tu ajoutes scrnsave.lib. Après tu peux passer à l'attaque (scrnsave.h est un fichier à inclure dans le code source (#include <scrnsave.h>), pas à "importer"). Un tutoriel sur la compilation séparée ne te fera pas non plus de mal, si t'as le temps de lire ...
Partager