Petit problème API Windows [Résolu]

Signaler
Messages postés
43
Date d'inscription
mercredi 22 avril 2009
Statut
Membre
Dernière intervention
18 octobre 2008
-
Messages postés
43
Date d'inscription
mercredi 22 avril 2009
Statut
Membre
Dernière intervention
18 octobre 2008
-
Bonjour,

je suis en train d'essayer d'apprendre comment fonctionne l'api windows ... j'ai a peu près compris comment afficher tout ce que je veux par contre ce que je n'ai pas compris c'est où je dois placer les instructions de calcul proprement dites dont je voudrait afficher les résultats avec l'api?
Il faut créer un thread parallèle et l'appeler dans winmain pour qu'il exécute à la fois ce thread de calcul tout en surveillant les messages windows?

Merci d'avance :)

4 réponses

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Salut,

Ca doit être moi, mais je trouve ça un peu vague comme question...

Tout dépend de ce que tu veux faire !

Si tu veux qu'un calcul se lance lors de l'appui sur un bouton, tu n'est pas forcément obligé de créer un thread pour exécuter les calculs. Si ceux si sont cours et que tu ne veux pas que l'utilisateur puisse utiliser ton application pendant le calcul, tu peux mettre directement le calcul dans le code gérant le clique du bouton. L'application sera frizée ("L'application ne répond pas" dans la barre" de titre, pas de rafraichissement) le temps du calcul, mais s'il est court, ce n'est pas un problème.

Si le calcul est long, tu vas devroir effectivement créer un thread supplémentaire qui sera chargé du calcul. Tu seras par contre peut être aussi obligé de limiter les possibilités de ton utilisateur, en rendant par exemple inactif le bouton de lancement de calcul pour qu'il ne puisse pas lancer un calcul alors que le calcul courant n'est pas terminé.

Question vague -> réponse vague... Mais j'espère ne pas avoir répondu trop à côté.

Bonne continuation.
Messages postés
43
Date d'inscription
mercredi 22 avril 2009
Statut
Membre
Dernière intervention
18 octobre 2008

Oui ce n'est pas très clair pardon ...
En fait j'ai un programme console (qui marche :D ) dont je récupère les résultats finaux dans un fichier. Mais j'aimerai bien afficher les résultats intermédiaires à l'écran en temps réel (il s'agit de 2 nuages de points superposés) ... Mais je ne sais pas trop à quel moment je dois appeler / insérer mon programme console ?

Merci quand meme pour ton début de réponse :)
Messages postés
43
Date d'inscription
mercredi 22 avril 2009
Statut
Membre
Dernière intervention
18 octobre 2008

Whaaa merciii !!!
J'ai pas trop le temps de me pencher dessus pour l'instant mais ça a l'air de très bien répondre à ma question :)
(surtout que d'après ce que je comprend je pourrai afficher plusieurs résultats dans des fenêtres différentes et ça m'arrange bien ^^)

Vraiment merci beaucoup !
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Ah oki. C'est un peu plus clair là.

Voilà ce que ça me donne (Win32/Console/C/jeu de caractère MBCS, testé sous Code::Blocks/gcc et VC6) :


<hr />

#include "windows.h"HINSTANCE _hThisInstance;              // Handle du module
HWND _hWnd;                            // Handle de la fenêtre
LPSTR _lpAppName = "TCHATTE";          // Nom de l'appli
HANDLE _hConsole;                      // Handle de la sortie standart
char _lpResult[50];                    // Résultat

/**
 * Affiche un message d'erreur correspondant à la dernière erreur Win32
 */
void ShowLastError()
{
  DWORD nLastError;
  LPSTR lpMessageBuffer;

  // Récupération du numéro de l'erreur
  nLastError = GetLastError();

  // Formatage du message
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMessageBuffer, 0, NULL);

  // Affichage du message et fin de l'appli
  MessageBox(NULL, lpMessageBuffer, "ERROR", MB_OK | MB_ICONERROR);
}

/**
 * Traitement des messages
 */
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT uPaintInfo;   // Information sur le dessin
  HDC hDC;

  switch (nMessage)
  {
    case WM_PAINT:
      hDC = BeginPaint(hWnd, &uPaintInfo);

      // Dessin de du résultat
      SetBkMode(hDC, TRANSPARENT);
      TextOut(hDC, 0, 0, _lpResult, lstrlen(_lpResult));

      EndPaint(hWnd, &uPaintInfo);
      return 0;
    case WM_DESTROY:
      // On signale que le thread va s'arrêter
      PostQuitMessage(0);
      break;
    default:
      // Application du traitement par défaut
      return DefWindowProc(hWnd, nMessage, wParam, lParam);
  }
  return 0;
}

/**
 * Initialise la fenêtre principale de l'appli.
 */
void InitWindow()
{
  WNDCLASSEX wincl;       // Classe de la fenêtre utilisée

  // Création de la classe de fenêtre
  wincl.cbSize = sizeof(WNDCLASSEX);
  wincl.style = 0;
  wincl.lpfnWndProc = WindowProcedure;
  wincl.cbClsExtra = 0;
  wincl.cbWndExtra = 0;
  wincl.hInstance = _hThisInstance;
  wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
  wincl.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  wincl.lpszMenuName = 0;
  wincl.lpszClassName = _lpAppName;
  wincl.hIconSm = NULL;

  // Enregistrement de la classe
  if (!RegisterClassEx(&wincl)) ShowLastError();

  // Création de la fenêtre
  _hWnd = CreateWindowEx(0, _lpAppName, _lpAppName, WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 300, 100, HWND_DESKTOP, NULL, _hThisInstance, NULL);
}

/**
 * Fonction de démarrage du thread, affichant le résultat intermédiaire
 */
DWORD WINAPI DisplayResult(LPVOID lpParameter)
{
  MSG messages;           // Réception des messages envoyés à l'application

  // Récupération du résultat dans une variable globale
  lstrcpy(_lpResult, lpParameter);

  InitWindow();

  // Boucle de traitement des messages
  while (GetMessage(&messages, NULL, 0, 0))
  {
    // Traduit certains messages
    TranslateMessage(&messages);

    // Distribution des messages aux fenêtres
    DispatchMessage(&messages);
  }

  // Code d'erreur en sortie
  return messages.wParam;
}

/**
 * Attend que l'utilisateur presse une touche
 */
void Pause()
{
  HANDLE hInput;    // Handle de l'entrée standard
  DWORD nRead;      // Nombre d'octets lus
  TCHAR buffer;     // Réception du caractère
  DWORD nOldMode;   // Sauvegarde le mode précédent pour le restituer

  hInput = GetStdHandle(STD_INPUT_HANDLE);
  GetConsoleMode(hInput, &nOldMode);
  SetConsoleMode(hInput, 0);
  ReadConsole(hInput, &buffer, 1, &nRead, NULL);
  SetConsoleMode(hInput, nOldMode);
}

/**
 * Simule un calcul
 */
void calculate(char c)
{
  int nCounter;     // Affichage des lettres
  DWORD nWritten;   // Nombres d'octets écrits

  // Ecrit régulièrement la lettre dans la console
  for (nCounter = 0 ; nCounter < 10 ; nCounter ++)
  {
    Sleep(250);
    WriteConsole(_hConsole, &c, 1, &nWritten, NULL);
  }
}

/**
 * Main
 */
#pragma comment(linker, "/entry:main")
int _cdecl main()
{
  DWORD nWritten;   // Nombres d'octets écrits
  HANDLE hThread;   // Handle du thread de la fenêtre du résultat
  char * lpWait = "\nPresser une touche pour continuer\n";
  char * lpResult = "Je suis le résultat";

  // Récupération d'un handle sur la sortie standard
  _hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

  // Récupération du handle du module
  _hThisInstance = GetModuleHandle(NULL);

  // Début du calcul
  calculate('d');

  // Affichage d'une fenêtre contenant un résultat intermédiaire
  hThread = CreateThread(NULL, 0, DisplayResult, lpResult, 0, NULL);

  // Fin du calcul
  calculate('f');

  // Attente d'une pression de touche
  WriteConsole(_hConsole, lpWait, lstrlen(lpWait), &nWritten, NULL);
  Pause();

  // Demande de fermeture de la fenêtre et fermeture du thread
  PostMessage(_hWnd, WM_CLOSE, 0, 0);
  WaitForSingleObject(hThread, INFINITE);
  CloseHandle(hThread);

  return 0;
}