Un petit programme pour les codes postaux

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 / Exemple :


#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.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.