|
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 !
UN PETIT PROGRAMME POUR LES CODES POSTAUX
Information sur la source
Description
Le progamme permet de trouver le code postal d'une ville, ou une ville à partir d'un code postal; jusque la rien de bien interressant, sauf que au niveau du code c'est la deferlante! (enfin en ce qui me concerne) threads, sempahores, cirtical section, gestion de fichiers, des messages: le tout en API pure... que du bonheur. A vous de juger. Au fait c'est 100% du C.
Source
- #include <windows.h>
- #include <tchar.h>
- #include <commctrl.h>
- #include <string.h>
- #include "resource.h"
-
- DWORD CALLBACK vcp_seeker_thread_proc (LPVOID param);
- BOOL CALLBACK vcp_dialog_proc (HWND hWnd,UINT msg,WPARAM wp,LPARAM lp);
-
- HANDLE sem;
- BOOL the_end = FALSE;
- TCHAR chaine[MAX_PATH];
- HWND liste,bouto,dlg;
- CRITICAL_SECTION cs;
- HANDLE thread;
-
- char tmp[MAX_PATH];
- char* offset = tmp;
- BOOL once = FALSE;
- int vcp_count = 0;
-
- struct vcp
- {
- struct vcp* next;
- LPSTR ville;
- unsigned cp;
- };
-
- struct vcp *debut = NULL;
-
- struct vcp* vcp_new()
- {
- struct vcp* n= (struct vcp*) malloc(sizeof(struct vcp));
-
- n->cp = 0;
- n->ville = NULL;
- n->next = NULL;
-
- return n;
- }
-
- void vcp_free(struct vcp** pp)
- {
- free((*pp)->ville);
- free(*pp);
- *pp = NULL;
- }
-
- //unsigned vcp_load(struct vcp* p,HANDLE file)
- unsigned vcp_load(struct vcp* p,char* o)
- {
- CHAR buf[MAX_PATH];
- CHAR cc[2];
- char* r = o;
-
- cc[1] = 0;
- *buf = 0;
-
- do
- {
- //ReadFile(file,cc,1,&c,NULL);
- memcpy(cc,o,sizeof(CHAR));
- o += sizeof(CHAR);
- strcat(buf,cc);
-
- }while(*cc);
-
- p->ville = strdup(buf);
-
- //ReadFile(file,&p->cp,sizeof(unsigned),&c,NULL);
- memcpy(&p->cp,o,4);
- o += 4;
-
- //r += c;
- return o - r;
- }
-
- HANDLE WINAPI start_thread(LPTHREAD_START_ROUTINE lpfn,LPVOID param)
- {
- DWORD id;
- return CreateThread(NULL,0,lpfn,param,0,&id);
- }
-
- int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR cmdLine,int cmdShow)
- {
- InitCommonControls(); // juste pour les themes de WinXP
-
- InitializeCriticalSection(&cs); //le mutex
- sem = CreateSemaphore(NULL,0,1,NULL); //le semaphore!
-
- //on donne la main au systeme pour la gestion des messages
- DialogBox(hInstance,MAKEINTRESOURCE(IDD_VCP),NULL,vcp_dialog_proc);
-
-
- //le systeme a rendu la main
- EnterCriticalSection(&cs);
- the_end = TRUE; // c'est fini, le thread va se terminer
- LeaveCriticalSection(&cs);
-
- ReleaseSemaphore(sem,1,NULL); //on le reveil s'il dormait
- WaitForSingleObject(thread,INFINITE); //on attend gentilement sa fin
-
-
- //fermeture en beaute de tout les objets
- CloseHandle(thread);
- CloseHandle(sem);
- DeleteCriticalSection(&cs);
-
- return 0;
- }
-
- LPCTSTR pluriel(unsigned int x)
- {
- return (x > 1 ? _T("s"): _T(""));
- }
-
- void update_status(HWND hWnd,unsigned x)
- {
- LPCTSTR msg = _T("%u ville%s trouvée%s");
- TCHAR buf[MAX_PATH];
-
- wsprintf(buf,msg,x, pluriel(x),pluriel(x));
-
- SetDlgItemText(hWnd,IDC_STATUS,buf);
- }
-
-
- void onTrouver(HWND hWnd)
- {
- GetWindowText(GetDlgItem(hWnd,IDC_TEXTE),chaine,MAX_PATH);
-
- EnterCriticalSection(&cs);
- once = FALSE;
- SendMessage(liste,LB_RESETCONTENT,(WPARAM) 0,(LPARAM) 0);
- SendMessage(GetDlgItem(hWnd,IDC_TEXTE),(UINT) EM_SETSEL,(WPARAM) 0,(LPARAM) -1);
- LeaveCriticalSection(&cs);
-
- //on reveille la bete
- ReleaseSemaphore(sem,1,NULL);
-
- }
-
- void onInitDialog(HWND hWnd)
- {
- HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hWnd,GWL_HINSTANCE);
-
- SendMessage(hWnd,WM_SETICON,ICON_BIG,(LPARAM) LoadIcon(hInstance,MAKEINTRESOURCE(IDI_VCP)));
-
- //EnterCriticalSection(&cs);
- liste = GetDlgItem(hWnd,IDC_LISTE);
- bouto = GetDlgItem(hWnd,IDC_TROUVER);
- //LeaveCriticalSection(&cs);
-
-
- //on cree le thread qui s'endort aussitot (cf sa procedure)
- thread = start_thread(vcp_seeker_thread_proc,hWnd);
- }
-
- long onCommand(HWND hWnd,WPARAM wp,LPARAM lp)
- {
- //boucle des messages des commandes principales
- switch(LOWORD(wp))
- {
- case IDC_TROUVER:
- onTrouver(hWnd);
- return 0;
- }
- return 1;
- }
-
- void onClose(HWND hWnd)
- {
- struct vcp* n, *p;
- for(n = debut ; n != NULL ; n = p)
- {
- p = n->next;
- vcp_free(&n);
- }
- debut = NULL;
- }
-
- BOOL CALLBACK vcp_dialog_proc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp)
- {
- //boucle des messages de la boite principal
- switch(msg)
- {
- case WM_INITDIALOG:
- dlg = hWnd;
- onInitDialog(hWnd);
- return TRUE;
-
- case WM_CLOSE:
- onClose(hWnd);
- PostQuitMessage(0);
- break;
-
- case WM_COMMAND:
- return onCommand(hWnd,wp,lp);
- }
- return FALSE;
- }
-
- void vcp_trouve(HWND hWnd)
- {
- static LPCTSTR filtre = _T("%.05i - %s");
- TCHAR buf[MAX_PATH];
- #ifdef UNICODE
- TCHAR v[MAX_PATH];
- #endif
- struct vcp* i;
- unsigned po;
- int nb = 0;
-
- if(!*chaine) //il faut au moins une chaine non vide
- {
- MessageBeep(MB_ICONEXCLAMATION);
- return;
- }
-
- #ifndef UNICODE
- po = strtoul(chaine,NULL,10);
- #else
- po = wcstoul(chaine,NULL,10);
- #endif
-
- for(i = debut ; i != NULL ; i = i->next)
- {
- #ifdef UNICODE
- mbstowcs(v,i->ville,strlen(i->ville) + 1);
- wsprintf(buf,filtre,i->cp,(LPCTSTR) v);
- #else
- wsprintf(buf,filtre,i->cp,(LPCTSTR) i->ville);
- #endif
-
- #ifdef UNICODE
- if(po == i->cp || po == i->cp/1000 || wcsstr(v,chaine))
- #else
- if(po == i->cp || po == i->cp/1000 || strstr(i->ville,chaine))
- #endif
- {
- if(!(++nb % 100))
- update_status(dlg,nb);
-
- SendMessage(liste,LB_ADDSTRING,0,(LPARAM) buf);
- }
- }
- update_status(dlg,nb);
- }
-
-
- // charge toute les donnees en memoire. sans blague!
- DWORD CALLBACK vcp_browser_thread_proc(LPVOID param)
- {
- HANDLE file = CreateFile(_T("vcp.bin"),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
- HANDLE map;
- struct vcp *c,*p;
- char* src, *offset;
- DWORD len;
- int nb = 0;
-
- if(file == INVALID_HANDLE_VALUE)
- return -1;
-
- if(!(map = CreateFileMapping(file,NULL,PAGE_READONLY,0,0,NULL)))
- return -2;
-
- if(!(src = (char*) MapViewOfFile(map,FILE_MAP_READ,0,0,0)))
- return -3;
-
-
- c = vcp_new();
- p = NULL;
- debut = c;
-
- offset = src;
- len = GetFileSize(file,NULL);
-
- while(offset < src + len)
- {
- offset += vcp_load(c,offset);
-
- if(!(++nb % 100))
- update_status(dlg,nb);
-
- p = c;
- c->next = vcp_new();
- c = c->next;
- vcp_count++;
- }
-
- update_status(dlg,nb);
-
- p->next = NULL;
- vcp_free(&c);
-
- UnmapViewOfFile(src);
- CloseHandle(map);
- CloseHandle(file);
-
- return 0;
- }
-
- DWORD CALLBACK vcp_seeker_thread_proc(LPVOID param)
- {
- HANDLE browser;
-
- //on demarre un thread pour le chargement
- //c'est superflue, mais tellement béau!
-
- EnableWindow(bouto,FALSE);
- //vcp_browser_thread_proc(NULL);
- browser = start_thread(vcp_browser_thread_proc,NULL);
- WaitForSingleObject(browser,INFINITE);
- //CloseHandle(browser);
-
- EnableWindow(bouto,TRUE);
-
-
- while(1) //boucle infini
- {
- if(the_end) //avant de se coucher on regarde si c'est pas la fin
- break;
-
- //on fait dodo jusqu'a qu'on nous sonne
- WaitForSingleObject(sem,INFINITE);
-
- if(the_end) //reveille trop tard? on s'arrache
- break;
-
- EnableWindow(bouto,FALSE);
- vcp_trouve((HWND) param); //c'est parti!
- EnableWindow(bouto,TRUE);
-
- }
-
- return -1;
- }
-
- void __pfnBkCheck(void) {} //evite la boite de dialogue...
-
- void _startup(void)
- {
- int code;
- HINSTANCE hInstance;
- LPSTR cmdLine;
- STARTUPINFO i;
-
- i.cb = sizeof i;
-
- GetStartupInfo(&i);
- hInstance = GetModuleHandle(NULL);
-
- cmdLine = GetCommandLineA();
-
- InitCommonControls();
- code = WinMain(hInstance,NULL,cmdLine,SW_SHOW);
-
- ExitProcess(code);
- }
#include <windows.h>
#include <tchar.h>
#include <commctrl.h>
#include <string.h>
#include "resource.h"
DWORD CALLBACK vcp_seeker_thread_proc (LPVOID param);
BOOL CALLBACK vcp_dialog_proc (HWND hWnd,UINT msg,WPARAM wp,LPARAM lp);
HANDLE sem;
BOOL the_end = FALSE;
TCHAR chaine[MAX_PATH];
HWND liste,bouto,dlg;
CRITICAL_SECTION cs;
HANDLE thread;
char tmp[MAX_PATH];
char* offset = tmp;
BOOL once = FALSE;
int vcp_count = 0;
struct vcp
{
struct vcp* next;
LPSTR ville;
unsigned cp;
};
struct vcp *debut = NULL;
struct vcp* vcp_new()
{
struct vcp* n= (struct vcp*) malloc(sizeof(struct vcp));
n->cp = 0;
n->ville = NULL;
n->next = NULL;
return n;
}
void vcp_free(struct vcp** pp)
{
free((*pp)->ville);
free(*pp);
*pp = NULL;
}
//unsigned vcp_load(struct vcp* p,HANDLE file)
unsigned vcp_load(struct vcp* p,char* o)
{
CHAR buf[MAX_PATH];
CHAR cc[2];
char* r = o;
cc[1] = 0;
*buf = 0;
do
{
//ReadFile(file,cc,1,&c,NULL);
memcpy(cc,o,sizeof(CHAR));
o += sizeof(CHAR);
strcat(buf,cc);
}while(*cc);
p->ville = strdup(buf);
//ReadFile(file,&p->cp,sizeof(unsigned),&c,NULL);
memcpy(&p->cp,o,4);
o += 4;
//r += c;
return o - r;
}
HANDLE WINAPI start_thread(LPTHREAD_START_ROUTINE lpfn,LPVOID param)
{
DWORD id;
return CreateThread(NULL,0,lpfn,param,0,&id);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR cmdLine,int cmdShow)
{
InitCommonControls(); // juste pour les themes de WinXP
InitializeCriticalSection(&cs); //le mutex
sem = CreateSemaphore(NULL,0,1,NULL); //le semaphore!
//on donne la main au systeme pour la gestion des messages
DialogBox(hInstance,MAKEINTRESOURCE(IDD_VCP),NULL,vcp_dialog_proc);
//le systeme a rendu la main
EnterCriticalSection(&cs);
the_end = TRUE; // c'est fini, le thread va se terminer
LeaveCriticalSection(&cs);
ReleaseSemaphore(sem,1,NULL); //on le reveil s'il dormait
WaitForSingleObject(thread,INFINITE); //on attend gentilement sa fin
//fermeture en beaute de tout les objets
CloseHandle(thread);
CloseHandle(sem);
DeleteCriticalSection(&cs);
return 0;
}
LPCTSTR pluriel(unsigned int x)
{
return (x > 1 ? _T("s"): _T(""));
}
void update_status(HWND hWnd,unsigned x)
{
LPCTSTR msg = _T("%u ville%s trouvée%s");
TCHAR buf[MAX_PATH];
wsprintf(buf,msg,x, pluriel(x),pluriel(x));
SetDlgItemText(hWnd,IDC_STATUS,buf);
}
void onTrouver(HWND hWnd)
{
GetWindowText(GetDlgItem(hWnd,IDC_TEXTE),chaine,MAX_PATH);
EnterCriticalSection(&cs);
once = FALSE;
SendMessage(liste,LB_RESETCONTENT,(WPARAM) 0,(LPARAM) 0);
SendMessage(GetDlgItem(hWnd,IDC_TEXTE),(UINT) EM_SETSEL,(WPARAM) 0,(LPARAM) -1);
LeaveCriticalSection(&cs);
//on reveille la bete
ReleaseSemaphore(sem,1,NULL);
}
void onInitDialog(HWND hWnd)
{
HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hWnd,GWL_HINSTANCE);
SendMessage(hWnd,WM_SETICON,ICON_BIG,(LPARAM) LoadIcon(hInstance,MAKEINTRESOURCE(IDI_VCP)));
//EnterCriticalSection(&cs);
liste = GetDlgItem(hWnd,IDC_LISTE);
bouto = GetDlgItem(hWnd,IDC_TROUVER);
//LeaveCriticalSection(&cs);
//on cree le thread qui s'endort aussitot (cf sa procedure)
thread = start_thread(vcp_seeker_thread_proc,hWnd);
}
long onCommand(HWND hWnd,WPARAM wp,LPARAM lp)
{
//boucle des messages des commandes principales
switch(LOWORD(wp))
{
case IDC_TROUVER:
onTrouver(hWnd);
return 0;
}
return 1;
}
void onClose(HWND hWnd)
{
struct vcp* n, *p;
for(n = debut ; n != NULL ; n = p)
{
p = n->next;
vcp_free(&n);
}
debut = NULL;
}
BOOL CALLBACK vcp_dialog_proc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp)
{
//boucle des messages de la boite principal
switch(msg)
{
case WM_INITDIALOG:
dlg = hWnd;
onInitDialog(hWnd);
return TRUE;
case WM_CLOSE:
onClose(hWnd);
PostQuitMessage(0);
break;
case WM_COMMAND:
return onCommand(hWnd,wp,lp);
}
return FALSE;
}
void vcp_trouve(HWND hWnd)
{
static LPCTSTR filtre = _T("%.05i - %s");
TCHAR buf[MAX_PATH];
#ifdef UNICODE
TCHAR v[MAX_PATH];
#endif
struct vcp* i;
unsigned po;
int nb = 0;
if(!*chaine) //il faut au moins une chaine non vide
{
MessageBeep(MB_ICONEXCLAMATION);
return;
}
#ifndef UNICODE
po = strtoul(chaine,NULL,10);
#else
po = wcstoul(chaine,NULL,10);
#endif
for(i = debut ; i != NULL ; i = i->next)
{
#ifdef UNICODE
mbstowcs(v,i->ville,strlen(i->ville) + 1);
wsprintf(buf,filtre,i->cp,(LPCTSTR) v);
#else
wsprintf(buf,filtre,i->cp,(LPCTSTR) i->ville);
#endif
#ifdef UNICODE
if(po == i->cp || po == i->cp/1000 || wcsstr(v,chaine))
#else
if(po == i->cp || po == i->cp/1000 || strstr(i->ville,chaine))
#endif
{
if(!(++nb % 100))
update_status(dlg,nb);
SendMessage(liste,LB_ADDSTRING,0,(LPARAM) buf);
}
}
update_status(dlg,nb);
}
// charge toute les donnees en memoire. sans blague!
DWORD CALLBACK vcp_browser_thread_proc(LPVOID param)
{
HANDLE file = CreateFile(_T("vcp.bin"),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
HANDLE map;
struct vcp *c,*p;
char* src, *offset;
DWORD len;
int nb = 0;
if(file == INVALID_HANDLE_VALUE)
return -1;
if(!(map = CreateFileMapping(file,NULL,PAGE_READONLY,0,0,NULL)))
return -2;
if(!(src = (char*) MapViewOfFile(map,FILE_MAP_READ,0,0,0)))
return -3;
c = vcp_new();
p = NULL;
debut = c;
offset = src;
len = GetFileSize(file,NULL);
while(offset < src + len)
{
offset += vcp_load(c,offset);
if(!(++nb % 100))
update_status(dlg,nb);
p = c;
c->next = vcp_new();
c = c->next;
vcp_count++;
}
update_status(dlg,nb);
p->next = NULL;
vcp_free(&c);
UnmapViewOfFile(src);
CloseHandle(map);
CloseHandle(file);
return 0;
}
DWORD CALLBACK vcp_seeker_thread_proc(LPVOID param)
{
HANDLE browser;
//on demarre un thread pour le chargement
//c'est superflue, mais tellement béau!
EnableWindow(bouto,FALSE);
//vcp_browser_thread_proc(NULL);
browser = start_thread(vcp_browser_thread_proc,NULL);
WaitForSingleObject(browser,INFINITE);
//CloseHandle(browser);
EnableWindow(bouto,TRUE);
while(1) //boucle infini
{
if(the_end) //avant de se coucher on regarde si c'est pas la fin
break;
//on fait dodo jusqu'a qu'on nous sonne
WaitForSingleObject(sem,INFINITE);
if(the_end) //reveille trop tard? on s'arrache
break;
EnableWindow(bouto,FALSE);
vcp_trouve((HWND) param); //c'est parti!
EnableWindow(bouto,TRUE);
}
return -1;
}
void __pfnBkCheck(void) {} //evite la boite de dialogue...
void _startup(void)
{
int code;
HINSTANCE hInstance;
LPSTR cmdLine;
STARTUPINFO i;
i.cb = sizeof i;
GetStartupInfo(&i);
hInstance = GetModuleHandle(NULL);
cmdLine = GetCommandLineA();
InitCommonControls();
code = WinMain(hInstance,NULL,cmdLine,SW_SHOW);
ExitProcess(code);
}
Conclusion
Je travail sur une mise à jour ultime! En C++ cette fois avec l'aide d'une lib que je developpe. En bref: gestion plus facile des messages, gestion des images png et jpeg... Tout un programme.
Historique
- 15 décembre 2004 16:00:30 :
- J'ai simplement ajouter le code en clair sur la source. Pour le comprendre sans le télécharger.
- 19 décembre 2004 01:33:28 :
- Correction du bug de lecture.
Mise a jour mineur du code.
- 16 janvier 2005 23:59:27 :
- Mise à jour mineur: toujours en C, amélioration du chargement (file mapping), libération de la mémoire à la fermeture, suppression de la barre de progression, gestion de l'unicode...
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Comparez les prix Nouvelle version
|