|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
CALENDRIER INCRUSTÉ SUR LE BUREAU [WIN32]
Information sur la source
Description
Cette source permet d'avoir un calendrier mensuel directement affiché sur le bureau.
Cette source permet notament de voir la techinque du double-buffering.
Pour ceux qui ne savent pas ce que c'est : rapide aperçu...
En gros si on dessine au fur et à mesure un dessin à l'écran à chaque fois qu'on recommence ça ferait apparaitre un clignotement. Pour éviter cela, on dessine dans un buffer (sorte d'écran virtuel) et quand le dessin est terminé on bascule le buffer à l'écran. Du coup on ne voit plus les étapes intermédiaires.
PS : pour configurer le calendrier (couelurs, positions, ...) c'est au tout début du code
Source
- //////////////////////////////////////////////////////////////
- // Include
- //////////////////////////////////////////////////////////////
-
- #include <windows.h>
- #include <stdio.h>
-
- //////////////////////////////////////////////////////////////
- // Paramètres du calendrier
- //////////////////////////////////////////////////////////////
-
- #define POSITION_X 700
- #define POSITION_Y 5
-
- #define ESPACEMENT_HORIZONTAL 30
- #define ESPACEMENT_VERTICAL 20
-
- #define FORECOLOR RGB(0,0,0)
- #define BACKCOLOR RGB(255,255,255)
- #define JOURCOLOR RGB(255,32,32)
-
- #define REFRESH_RATE 1000
-
- //////////////////////////////////////////////////////////////
- // Variables globales
- //////////////////////////////////////////////////////////////
-
- HWND hDesk;
- RECT fullRect;
-
- short nJours[6][7];
- SYSTEMTIME st;
-
- char* cJours[7];
-
- //////////////////////////////////////////////////////////////
- // Fonctions
- //////////////////////////////////////////////////////////////
-
- /**
- * Récupère le HWND du bureau
- */
- HWND FindDesktopWindow()
- {
- HWND hWnd = FindWindow("Progman", "Program Manager");
-
- if(GetParent(hWnd) == NULL)
- {
- HWND hWndEnfant = GetWindow(hWnd, GW_CHILD);
- char szBuf[32];
-
- while(hWndEnfant != NULL)
- {
- GetClassName(hWndEnfant, szBuf, sizeof(szBuf));
- if(lstrcmp(szBuf, "SHELLDLL_DefView") == 0)
- break;
- hWndEnfant = GetWindow(hWndEnfant, GW_HWNDNEXT);
- }
-
- if(hWndEnfant != NULL)
- {
- hWndEnfant = GetWindow(hWndEnfant, GW_CHILD);
- while(hWndEnfant != NULL)
- {
- GetClassName(hWndEnfant, szBuf, sizeof(szBuf));
- if(lstrcmp(szBuf, "SysListView32") == 0)
- break;
- hWndEnfant = GetWindow(hWndEnfant, GW_HWNDNEXT);
- }
- if(hWndEnfant != NULL)
- return hWndEnfant;
- }
- }
-
- return GetDesktopWindow();
- }
-
- /**
- * Dessine le calendrier sans ombre
- *
- * hDC : DC où le calendrier est dessiné
- * bFore : TRUE si c'est le calendrier d'avant-plan qui doit être dessiné FALSE sinon (ombre)
- */
- void DessineCalendrierAux(HDC hDC, BOOL bFore)
- {
- int i, j;
- char nDecalage;
- RECT rect;
-
- // Si c'est le dessin du texte d'avant plan il n'y a aps de décalage, sinon il y a un décalage de 1 pixel
- nDecalage = bFore ? 0 : 1;
-
- SetTextColor(hDC, bFore ? FORECOLOR : BACKCOLOR);
-
-
- SetBkMode(hDC, TRANSPARENT);
-
- for (j=0; j<7; j++)
- {
- // jours de la semaine
- rect.left = nDecalage + j *ESPACEMENT_HORIZONTAL;
- rect.right = nDecalage + (j+1)*ESPACEMENT_HORIZONTAL;
- rect.top = nDecalage;
- rect.bottom = nDecalage + ESPACEMENT_VERTICAL;
-
- DrawText(hDC, cJours[j], 1, &rect, DT_CENTER);
-
- for (i=0; i<6; i++)
- {
- // numéro des jours du mois
- char numero[2] = "";
- if (nJours[i][j]>0)
- {
- sprintf(numero, "%d", nJours[i][j]);
-
- rect.top = nDecalage + (i+1)*ESPACEMENT_VERTICAL;
- rect.bottom = nDecalage + (i+2)*ESPACEMENT_VERTICAL;
-
- if (nJours[i][j]==st.wDay && nDecalage == 0)
- Arc( hDC, rect.left, rect.top-1, rect.right, rect.bottom-1, 0, 0, 0, 0);
-
- DrawText(hDC, numero, strlen(numero), &rect, DT_CENTER);
- }
- }
- }
- }
-
- /**
- * Dessine le calendrier ombré (utilisation du double buffering
- */
- void DessineCalendrier(HDC hDeskDC)
- {
- HDC hDC;
- DWORD dwWidth, dwHeight, dwNumColors, dwBPP;
- void *pBits;
- HBITMAP hbmp;
- BITMAPINFO bmpinfo;
- HPEN hPen;
-
- // Dimensions du buffer
- dwWidth = fullRect.right - fullRect.left;
- dwHeight = fullRect.bottom - fullRect.top;
- dwBPP = GetDeviceCaps(hDeskDC, BITSPIXEL);
- if(dwBPP <= 8)
- dwNumColors = 256;
- else
- dwNumColors = 0;
-
- // Initialisation du buffer
- bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmpinfo.bmiHeader.biWidth = dwWidth;
- bmpinfo.bmiHeader.biHeight = dwHeight;
- bmpinfo.bmiHeader.biPlanes = 1;
- bmpinfo.bmiHeader.biBitCount = (WORD) dwBPP;
- bmpinfo.bmiHeader.biCompression = BI_RGB;
- bmpinfo.bmiHeader.biSizeImage = 0;
- bmpinfo.bmiHeader.biXPelsPerMeter = 0;
- bmpinfo.bmiHeader.biYPelsPerMeter = 0;
- bmpinfo.bmiHeader.biClrUsed = dwNumColors;
- bmpinfo.bmiHeader.biClrImportant = dwNumColors;
- hbmp = CreateDIBSection(hDeskDC, &bmpinfo, DIB_PAL_COLORS, &pBits, NULL, 0);
-
- // Création du buffer et copie de la zone de l'écran concernée
- hDC = CreateCompatibleDC(hDeskDC);
- SelectObject(hDC, hbmp);
- BitBlt(hDC, 0, 0, dwWidth, dwHeight, hDeskDC, fullRect.left, fullRect.top, SRCCOPY);
-
- // Couleur pour l'ellipse
- hPen = CreatePen(PS_SOLID, 1, JOURCOLOR);
- SelectObject(hDC, hPen);
-
- // Dessine la partie en arriere plan (l'ombre)
- DessineCalendrierAux(hDC, FALSE);
- // Dessine la partie en avant-plan
- DessineCalendrierAux(hDC, TRUE);
-
- // Copie du buffer sur le bureau
- BitBlt(hDeskDC, POSITION_X, POSITION_Y, dwWidth, dwHeight, hDC, 0, 0, SRCCOPY);
-
- DeleteObject(hbmp);
- DeleteObject(hPen);
- DeleteDC(hDC);
-
- }
-
- /**
- * Initialisation de valeurs necessaires au graphisme
- */
- void InitCalendrierGraphique()
- {
- // Rect du calendrier
- fullRect.left = POSITION_X;
- fullRect.top = POSITION_Y;
- fullRect.right = POSITION_X + 7*ESPACEMENT_HORIZONTAL;
- fullRect.bottom = POSITION_Y + 7*ESPACEMENT_VERTICAL;
- }
-
- /**
- * Initialise le tableau du calendrier
- */
- void RemplitCalendrier()
- {
- short nPremierJour;
- short nJoursParMois[13];
- short nombreJours;
- short nCase, day;
- char i,j;
-
- // Récupère la date du jour
- GetLocalTime(&st);
-
- // Le premier jour du mois est-il un lundi, mardi ,... ?
- nPremierJour = (st.wDayOfWeek - st.wDay + 1 + 5*7) % 7;
- if (nPremierJour==0)
- nPremierJour=7;
-
- // Nombre de jours par mois
- nJoursParMois[0] = 0;
- nJoursParMois[1] = 31;
- nJoursParMois[2] = 28;
- nJoursParMois[3] = 31;
- nJoursParMois[4] = 30;
- nJoursParMois[5] = 31;
- nJoursParMois[6] = 30;
- nJoursParMois[7] = 31;
- nJoursParMois[8] = 31;
- nJoursParMois[9] = 30;
- nJoursParMois[10] = 31;
- nJoursParMois[11] = 30;
- nJoursParMois[12] = 31;
-
- // Année bissextile (facile entre 1980 et 2099)
- if (st.wMonth%4==0)
- nJoursParMois[2]++;
-
- // Nombre de jours pour le mois en cours
- nombreJours = nJoursParMois[st.wMonth];
-
- // On remplit le calendrier
- for (i = 0; i<6; i++)
- for (j = 0; j<7; j++)
- {
- nCase = 7*i + j;
-
- day = nCase - nPremierJour + 2;
-
- nJours[i][j] = day>0 && day<=nombreJours ? day :0;
- }
-
- // Lettres qui représentent les jours de la semaine
- cJours[0] = "L";
- cJours[1] = "M";
- cJours[2] = "M";
- cJours[3] = "J";
- cJours[4] = "V";
- cJours[5] = "S";
- cJours[6] = "D";
- }
-
- /**
- * Fonction appelée périodiquement pour relancer le dessin du calendrier
- */
- void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT uTimerId, DWORD dwTime)
- {
- HDC hDC;
- SYSTEMTIME st_recent;
-
- // Si la date a changé, mettre à jour le calendrier
- GetLocalTime(&st_recent);
- if (st_recent.wDay != st.wDay || st_recent.wMonth != st.wMonth || st_recent.wYear != st.wYear)
- {
- InvalidateRect(NULL, NULL, TRUE);
- RemplitCalendrier();
- }
-
- // Dessine le calendrier
- if(hDC = GetDC(hDesk))
- {
- DessineCalendrier(hDC);
- ReleaseDC(hDesk, hDC);
- }
- }
-
- /**
- * Point d'entrée
- */
- int WINAPI WinMain(HINSTANCE hThisInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpszArgument,
- int iCmdShow)
- {
- MSG msg;
- DWORD dwPid;
-
- hDesk = FindDesktopWindow();
- InitCalendrierGraphique();
- RemplitCalendrier();
-
- dwPid = GetWindowThreadProcessId(hDesk, NULL);
- if(!AttachThreadInput(dwPid, GetCurrentThreadId(), TRUE))
- return 0;
-
- SetTimer(NULL, 0, REFRESH_RATE, TimerProc);
-
- while(GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- AttachThreadInput(dwPid, GetCurrentThreadId(), FALSE);
- KillTimer(NULL, 0);
-
- return msg.wParam;
- }
//////////////////////////////////////////////////////////////
// Include
//////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////
// Paramètres du calendrier
//////////////////////////////////////////////////////////////
#define POSITION_X 700
#define POSITION_Y 5
#define ESPACEMENT_HORIZONTAL 30
#define ESPACEMENT_VERTICAL 20
#define FORECOLOR RGB(0,0,0)
#define BACKCOLOR RGB(255,255,255)
#define JOURCOLOR RGB(255,32,32)
#define REFRESH_RATE 1000
//////////////////////////////////////////////////////////////
// Variables globales
//////////////////////////////////////////////////////////////
HWND hDesk;
RECT fullRect;
short nJours[6][7];
SYSTEMTIME st;
char* cJours[7];
//////////////////////////////////////////////////////////////
// Fonctions
//////////////////////////////////////////////////////////////
/**
* Récupère le HWND du bureau
*/
HWND FindDesktopWindow()
{
HWND hWnd = FindWindow("Progman", "Program Manager");
if(GetParent(hWnd) == NULL)
{
HWND hWndEnfant = GetWindow(hWnd, GW_CHILD);
char szBuf[32];
while(hWndEnfant != NULL)
{
GetClassName(hWndEnfant, szBuf, sizeof(szBuf));
if(lstrcmp(szBuf, "SHELLDLL_DefView") == 0)
break;
hWndEnfant = GetWindow(hWndEnfant, GW_HWNDNEXT);
}
if(hWndEnfant != NULL)
{
hWndEnfant = GetWindow(hWndEnfant, GW_CHILD);
while(hWndEnfant != NULL)
{
GetClassName(hWndEnfant, szBuf, sizeof(szBuf));
if(lstrcmp(szBuf, "SysListView32") == 0)
break;
hWndEnfant = GetWindow(hWndEnfant, GW_HWNDNEXT);
}
if(hWndEnfant != NULL)
return hWndEnfant;
}
}
return GetDesktopWindow();
}
/**
* Dessine le calendrier sans ombre
*
* hDC : DC où le calendrier est dessiné
* bFore : TRUE si c'est le calendrier d'avant-plan qui doit être dessiné FALSE sinon (ombre)
*/
void DessineCalendrierAux(HDC hDC, BOOL bFore)
{
int i, j;
char nDecalage;
RECT rect;
// Si c'est le dessin du texte d'avant plan il n'y a aps de décalage, sinon il y a un décalage de 1 pixel
nDecalage = bFore ? 0 : 1;
SetTextColor(hDC, bFore ? FORECOLOR : BACKCOLOR);
SetBkMode(hDC, TRANSPARENT);
for (j=0; j<7; j++)
{
// jours de la semaine
rect.left = nDecalage + j *ESPACEMENT_HORIZONTAL;
rect.right = nDecalage + (j+1)*ESPACEMENT_HORIZONTAL;
rect.top = nDecalage;
rect.bottom = nDecalage + ESPACEMENT_VERTICAL;
DrawText(hDC, cJours[j], 1, &rect, DT_CENTER);
for (i=0; i<6; i++)
{
// numéro des jours du mois
char numero[2] = "";
if (nJours[i][j]>0)
{
sprintf(numero, "%d", nJours[i][j]);
rect.top = nDecalage + (i+1)*ESPACEMENT_VERTICAL;
rect.bottom = nDecalage + (i+2)*ESPACEMENT_VERTICAL;
if (nJours[i][j]==st.wDay && nDecalage == 0)
Arc( hDC, rect.left, rect.top-1, rect.right, rect.bottom-1, 0, 0, 0, 0);
DrawText(hDC, numero, strlen(numero), &rect, DT_CENTER);
}
}
}
}
/**
* Dessine le calendrier ombré (utilisation du double buffering
*/
void DessineCalendrier(HDC hDeskDC)
{
HDC hDC;
DWORD dwWidth, dwHeight, dwNumColors, dwBPP;
void *pBits;
HBITMAP hbmp;
BITMAPINFO bmpinfo;
HPEN hPen;
// Dimensions du buffer
dwWidth = fullRect.right - fullRect.left;
dwHeight = fullRect.bottom - fullRect.top;
dwBPP = GetDeviceCaps(hDeskDC, BITSPIXEL);
if(dwBPP <= 8)
dwNumColors = 256;
else
dwNumColors = 0;
// Initialisation du buffer
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biWidth = dwWidth;
bmpinfo.bmiHeader.biHeight = dwHeight;
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biBitCount = (WORD) dwBPP;
bmpinfo.bmiHeader.biCompression = BI_RGB;
bmpinfo.bmiHeader.biSizeImage = 0;
bmpinfo.bmiHeader.biXPelsPerMeter = 0;
bmpinfo.bmiHeader.biYPelsPerMeter = 0;
bmpinfo.bmiHeader.biClrUsed = dwNumColors;
bmpinfo.bmiHeader.biClrImportant = dwNumColors;
hbmp = CreateDIBSection(hDeskDC, &bmpinfo, DIB_PAL_COLORS, &pBits, NULL, 0);
// Création du buffer et copie de la zone de l'écran concernée
hDC = CreateCompatibleDC(hDeskDC);
SelectObject(hDC, hbmp);
BitBlt(hDC, 0, 0, dwWidth, dwHeight, hDeskDC, fullRect.left, fullRect.top, SRCCOPY);
// Couleur pour l'ellipse
hPen = CreatePen(PS_SOLID, 1, JOURCOLOR);
SelectObject(hDC, hPen);
// Dessine la partie en arriere plan (l'ombre)
DessineCalendrierAux(hDC, FALSE);
// Dessine la partie en avant-plan
DessineCalendrierAux(hDC, TRUE);
// Copie du buffer sur le bureau
BitBlt(hDeskDC, POSITION_X, POSITION_Y, dwWidth, dwHeight, hDC, 0, 0, SRCCOPY);
DeleteObject(hbmp);
DeleteObject(hPen);
DeleteDC(hDC);
}
/**
* Initialisation de valeurs necessaires au graphisme
*/
void InitCalendrierGraphique()
{
// Rect du calendrier
fullRect.left = POSITION_X;
fullRect.top = POSITION_Y;
fullRect.right = POSITION_X + 7*ESPACEMENT_HORIZONTAL;
fullRect.bottom = POSITION_Y + 7*ESPACEMENT_VERTICAL;
}
/**
* Initialise le tableau du calendrier
*/
void RemplitCalendrier()
{
short nPremierJour;
short nJoursParMois[13];
short nombreJours;
short nCase, day;
char i,j;
// Récupère la date du jour
GetLocalTime(&st);
// Le premier jour du mois est-il un lundi, mardi ,... ?
nPremierJour = (st.wDayOfWeek - st.wDay + 1 + 5*7) % 7;
if (nPremierJour==0)
nPremierJour=7;
// Nombre de jours par mois
nJoursParMois[0] = 0;
nJoursParMois[1] = 31;
nJoursParMois[2] = 28;
nJoursParMois[3] = 31;
nJoursParMois[4] = 30;
nJoursParMois[5] = 31;
nJoursParMois[6] = 30;
nJoursParMois[7] = 31;
nJoursParMois[8] = 31;
nJoursParMois[9] = 30;
nJoursParMois[10] = 31;
nJoursParMois[11] = 30;
nJoursParMois[12] = 31;
// Année bissextile (facile entre 1980 et 2099)
if (st.wMonth%4==0)
nJoursParMois[2]++;
// Nombre de jours pour le mois en cours
nombreJours = nJoursParMois[st.wMonth];
// On remplit le calendrier
for (i = 0; i<6; i++)
for (j = 0; j<7; j++)
{
nCase = 7*i + j;
day = nCase - nPremierJour + 2;
nJours[i][j] = day>0 && day<=nombreJours ? day :0;
}
// Lettres qui représentent les jours de la semaine
cJours[0] = "L";
cJours[1] = "M";
cJours[2] = "M";
cJours[3] = "J";
cJours[4] = "V";
cJours[5] = "S";
cJours[6] = "D";
}
/**
* Fonction appelée périodiquement pour relancer le dessin du calendrier
*/
void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT uTimerId, DWORD dwTime)
{
HDC hDC;
SYSTEMTIME st_recent;
// Si la date a changé, mettre à jour le calendrier
GetLocalTime(&st_recent);
if (st_recent.wDay != st.wDay || st_recent.wMonth != st.wMonth || st_recent.wYear != st.wYear)
{
InvalidateRect(NULL, NULL, TRUE);
RemplitCalendrier();
}
// Dessine le calendrier
if(hDC = GetDC(hDesk))
{
DessineCalendrier(hDC);
ReleaseDC(hDesk, hDC);
}
}
/**
* Point d'entrée
*/
int WINAPI WinMain(HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int iCmdShow)
{
MSG msg;
DWORD dwPid;
hDesk = FindDesktopWindow();
InitCalendrierGraphique();
RemplitCalendrier();
dwPid = GetWindowThreadProcessId(hDesk, NULL);
if(!AttachThreadInput(dwPid, GetCurrentThreadId(), TRUE))
return 0;
SetTimer(NULL, 0, REFRESH_RATE, TimerProc);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
AttachThreadInput(dwPid, GetCurrentThreadId(), FALSE);
KillTimer(NULL, 0);
return msg.wParam;
}
Conclusion
Je me suis inspiré de 2 autres sources :
- celle de Brunews sur la sauvegarde des HDC dans des fichiers BMP :
http://www.cppfrance.com/code.aspx?ID=11128
-et celle de magma : "ANIMEZ VOTRE BUREAU"
http://www.cppfrance.com/code.aspx?ID=16843
Merci à eux
MISE A JOUR : 22/11/2003
Si la date change pendant le fonctionnement du calendrier, il se met à jour
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Comparez les prix Nouvelle version
|