Telnet en c avec interface graphique (api uniquement, sans mfc ni autres cochonneries)

Soyez le premier à donner votre avis sur cette source.

Snippet vu 9 518 fois - Téléchargée 33 fois

Contenu du snippet

Bon, 2e tentative...

Je disais donc que cette source fait suite à mon ancien telnet console... Celui-ci dispose d'une GUI et permet d'envoyer des requêtes HTTP en une seule fois (ne pas oublier d'appuyer sur entrée après chaque ligne dans le memo d'envoi, le prog ne rajoute pas les CRLF...)

Source / Exemple :


#include <windows.h>
#include <winsock2.h>

#define WND_CLASS "GWIN32_TELNET"

#define IDB_CONNECT 1
#define IDB_DISCONNECT 2
#define IDB_SEND 3

#define IDE_HOST 1
#define IDE_PORT 2
#define IDE_COMMAND 3

HINSTANCE hMain = NULL;
HFONT hFont = NULL;

HWND wndMain = NULL;
HWND stcHost = NULL;
HWND edtHost = NULL;
HWND stcPort = NULL;
HWND edtPort = NULL;
HWND btnConnect = NULL;
HWND btnDisconnect = NULL;
HWND stcTransfer = NULL;
HWND edtTransfer = NULL;
HWND stcCommand = NULL;
HWND edtCommand = NULL;
HWND btnSend = NULL;

WSADATA WSAData;
char* host = NULL;
char* port = NULL;
BOOL bWinsock = FALSE;
CRITICAL_SECTION lock;
SOCKADDR_IN ClientSock;
SOCKET Client = INVALID_SOCKET;
HOSTENT* ServerInfos = NULL;
HANDLE RecvThread = NULL;
DWORD RecvThreadID = 0;
DWORD RecvThreadExitCode = 0;

void AddLine(char* c, BOOL r) {
  int n = 0;
  EnterCriticalSection(&lock);
  n = SendMessage(edtTransfer, WM_GETTEXTLENGTH, 0, 0) + 1;
  SendMessage(edtTransfer, EM_SETSEL, n, n);
  SendMessage(edtTransfer, EM_REPLACESEL, TRUE, (LPARAM) c);
  if (r) SendMessage(edtTransfer, EM_REPLACESEL, TRUE, (LPARAM) "\r\n");
  LeaveCriticalSection(&lock);
  UpdateWindow(wndMain);
}

void ResetControls(BOOL FromThread) {
  EnableWindow(edtTransfer, TRUE);
  if (RecvThread) {
    GetExitCodeThread(RecvThread, &RecvThreadExitCode);
    if (RecvThreadExitCode == STILL_ACTIVE && !FromThread) TerminateThread(RecvThread, 0);
    CloseHandle(RecvThread);
    RecvThread = NULL;
    closesocket(Client);
    Client = INVALID_SOCKET;
    SetFocus(edtTransfer);
  }
  if (host) {
    free(host);
    host = NULL;
  }
  if (port) {
    free(port);
    port = NULL;
  }
  EnableWindow(stcHost, bWinsock);
  EnableWindow(edtHost, bWinsock);
  EnableWindow(stcPort, bWinsock);
  EnableWindow(edtPort, bWinsock);
  EnableWindow(btnConnect, bWinsock);
  EnableWindow(btnDisconnect, FALSE);
  EnableWindow(stcTransfer, FALSE);
  EnableWindow(stcCommand, FALSE);
  EnableWindow(edtCommand, FALSE);
  EnableWindow(btnSend, FALSE);
  UpdateWindow(wndMain);
}

DWORD WINAPI ClientRecv(void* arg) {
  int n = 0;
  char c = 0;
  char* line = NULL;
  while (recv(Client, &c, 1, 0) > 0) {
    line = (char*) realloc(line, n + 1);
    line[n++] = c;
    if (c != '\n') continue;
    line = (char*) realloc(line, n + 1);
    line[n++] = 0;
    AddLine(line, FALSE);
    free(line);
    line = NULL;
    n = 0;
  }
  AddLine("\r\n\r\nDéconnecté du serveur.", TRUE);
  ResetControls(TRUE);
  return 0;
}

LRESULT CALLBACK wndMainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  int n = 0;
  char* line = NULL;
  switch (uMsg) {
  case WM_ACTIVATE:
    if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) SetFocus(edtCommand);
    return 0;
  case WM_COMMAND:
    switch (HIWORD(wParam)) {
    case EN_CHANGE:
      switch (LOWORD(wParam)) {
      case IDE_HOST:
        EnableWindow(btnConnect, bWinsock && SendMessage(edtHost, WM_GETTEXTLENGTH, 0, 0) > 0 && SendMessage(edtPort, WM_GETTEXTLENGTH, 0, 0) > 0);
        break;
      case IDE_PORT:
        EnableWindow(btnConnect, bWinsock && SendMessage(edtHost, WM_GETTEXTLENGTH, 0, 0) > 0 && SendMessage(edtPort, WM_GETTEXTLENGTH, 0, 0) > 0);
        break;
      case IDE_COMMAND:
        EnableWindow(btnSend, SendMessage(edtCommand, WM_GETTEXTLENGTH, 0, 0) > 0);
        break;
      }
      break;
    case BN_CLICKED:
      switch (LOWORD(wParam)) {
      case IDB_CONNECT:
        EnableWindow(stcHost, FALSE);
        EnableWindow(edtHost, FALSE);
        EnableWindow(stcPort, FALSE);
        EnableWindow(edtPort, FALSE);
        EnableWindow(btnConnect, FALSE);
        n = SendMessage(edtHost, WM_GETTEXTLENGTH, 0, 0) + 1;
        host = (char*) malloc(n);
        SendMessage(edtHost, WM_GETTEXT, n, (LPARAM) host);
        n = SendMessage(edtPort, WM_GETTEXTLENGTH, 0, 0) + 1;
        port = (char*) malloc(n);
        SendMessage(edtPort, WM_GETTEXT, n, (LPARAM) port);
        SendMessage(edtTransfer, WM_SETTEXT, 0, (LPARAM) "");
        AddLine("Recherche du serveur... ", FALSE);
        ServerInfos = gethostbyname(host);
        if (!ServerInfos) {
          AddLine("erreur", TRUE);
          ResetControls(FALSE);
          break;
        }
        AddLine("ok", TRUE);
        memset(&ClientSock, 0, sizeof(SOCKADDR_IN));
        memcpy(&ClientSock.sin_addr.s_addr, ServerInfos->h_addr, ServerInfos->h_length);
        ClientSock.sin_port = htons(atoi(port));
        ClientSock.sin_family = AF_INET;
        Client = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        AddLine("Connexion au serveur... ", FALSE);
        if (connect(Client, (SOCKADDR*) &ClientSock, sizeof(SOCKADDR_IN))) {
          AddLine("erreur", TRUE);
          ResetControls(FALSE);
          break;
        }
        SendMessage(edtTransfer, WM_SETTEXT, 0, (LPARAM) "");
        EnableWindow(btnDisconnect, TRUE);
        EnableWindow(stcTransfer, TRUE);
        EnableWindow(edtTransfer, TRUE);
        EnableWindow(stcCommand, TRUE);
        EnableWindow(edtCommand, TRUE);
        EnableWindow(btnSend, TRUE);
        SetFocus(edtCommand);
        UpdateWindow(wndMain);
        RecvThread = CreateThread(NULL, 0, &ClientRecv, &Client, 0, &RecvThreadID);
        break;
      case IDB_DISCONNECT:
        ResetControls(FALSE);
        break;
      case IDB_SEND:
        SetFocus(edtCommand);
        n = SendMessage(edtCommand, WM_GETTEXTLENGTH, 0, 0) + 1;
        line = (char*) malloc(n);
        SendMessage(edtCommand, WM_GETTEXT, n, (LPARAM) line);
        SendMessage(edtCommand, WM_SETTEXT, 0, (LPARAM) "");
        AddLine("=> ", FALSE);
        AddLine(line, FALSE);
        send(Client, line, n - 1, 0);
        free(line);
        UpdateWindow(wndMain);
        break;
      }
      break;
    }
    return 0;
  case WM_CLOSE:
    PostQuitMessage(0);
    return 0;
  default:
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  MSG msg;
  WNDCLASSEX wc;
  hMain = hInstance;
  wc.cbSize = sizeof(WNDCLASSEX);
  wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = wndMainProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hMain;
  wc.hIcon = LoadIcon(hMain, "MAINICON");
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
  wc.lpszMenuName = NULL;
  wc.lpszClassName = WND_CLASS;
  wc.hIconSm = NULL;
  RegisterClassEx(&wc);
  InitializeCriticalSection(&lock);
  hFont = CreateFont(8, 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "MS Sans Serif");
  wndMain = CreateWindowEx(0, WND_CLASS, "Telnet Win32", WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 460, 540, HWND_DESKTOP, NULL, hMain, NULL);
  SendMessage(wndMain, WM_SETFONT, (WPARAM) hFont, TRUE);
  stcHost = CreateWindowEx(0, "STATIC", "Hôte :", WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP, 10, 10, 30, 14, wndMain, NULL, hMain, NULL);
  SendMessage(stcHost, WM_SETFONT, (WPARAM) hFont, TRUE);
  edtHost = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "EDIT", "127.0.0.1", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_LOWERCASE, 46, 6, 300, 21, wndMain, (HMENU) IDE_HOST, hMain, NULL);
  SendMessage(edtHost, WM_SETFONT, (WPARAM) hFont, TRUE);
  stcPort = CreateWindowEx(0, "STATIC", "Port :", WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP, 10, 35, 30, 14, wndMain, NULL, hMain, NULL);
  SendMessage(stcPort, WM_SETFONT, (WPARAM) hFont, TRUE);
  edtPort = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "EDIT", "23", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_LOWERCASE, 46, 31, 300, 21, wndMain, (HMENU) IDE_PORT, hMain, NULL);
  SendMessage(edtPort, WM_SETFONT, (WPARAM) hFont, TRUE);
  btnConnect = CreateWindowEx(0, "BUTTON", "Connexion", WS_CHILD | WS_VISIBLE | BS_TEXT | BS_CENTER | BS_VCENTER | BS_PUSHBUTTON | BS_NOTIFY, 360, 6, 80, 21, wndMain, (HMENU) IDB_CONNECT, hMain, NULL);
  SendMessage(btnConnect, WM_SETFONT, (WPARAM) hFont, TRUE);
  btnDisconnect = CreateWindowEx(0, "BUTTON", "Déconnexion", WS_CHILD | WS_VISIBLE | BS_TEXT | BS_CENTER | BS_VCENTER | BS_PUSHBUTTON | BS_NOTIFY, 360, 31, 80, 21, wndMain, (HMENU) IDB_DISCONNECT, hMain, NULL);
  SendMessage(btnDisconnect, WM_SETFONT, (WPARAM) hFont, TRUE);
  stcTransfer = CreateWindowEx(0, "STATIC", "Transferts :", WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP, 10, 60, 60, 14, wndMain, NULL, hMain, NULL);
  SendMessage(stcTransfer, WM_SETFONT, (WPARAM) hFont, TRUE);
  edtTransfer = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_READONLY | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 10, 75, 431, 300, wndMain, NULL, hMain, NULL);
  SendMessage(edtTransfer, WM_SETFONT, (WPARAM) hFont, TRUE);
  stcCommand = CreateWindowEx(0, "STATIC", "Requête :", WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP, 10, 380, 60, 14, wndMain, NULL, hMain, NULL);
  SendMessage(stcCommand, WM_SETFONT, (WPARAM) hFont, TRUE);
  edtCommand = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 10, 398, 431, 104, wndMain, (HMENU) IDE_COMMAND, hMain, NULL);
  SendMessage(edtCommand, WM_SETFONT, (WPARAM) hFont, TRUE);
  btnSend = CreateWindowEx(0, "BUTTON", "Envoyer", WS_CHILD | WS_VISIBLE | BS_TEXT | BS_CENTER | BS_VCENTER | BS_PUSHBUTTON | BS_NOTIFY, 360, 376, 80, 21, wndMain, (HMENU) IDB_SEND, hMain, NULL);
  SendMessage(btnSend, WM_SETFONT, (WPARAM) hFont, TRUE);
  AddLine("Initialisation de winsock... ", FALSE);
  bWinsock = !WSAStartup(MAKEWORD(2, 2), &WSAData);
  if (bWinsock) AddLine("ok", TRUE);
  else AddLine("erreur", TRUE);
  ResetControls(FALSE);
  ShowWindow(wndMain, SW_SHOW);
  while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  ResetControls(FALSE);
  DestroyWindow(wndMain);
  DeleteCriticalSection(&lock);
  DeleteObject(hFont);
  WSACleanup();
  return msg.wParam;
}

Conclusion :


Si y'a des maladresses, hésitez pas à les pointer du doigt, c'est ma toute première application graphique ;)

MAJ : placement du focus sur edtCommand... çà peut sembler inutile mais lorsqu'on utilise le prog quotidiennement, c'est appréciable ;)

PS: désolé pour le manque de commentaires...

A voir également

Ajouter un commentaire

Commentaires

Krox68
Messages postés
157
Date d'inscription
jeudi 17 octobre 2002
Statut
Membre
Dernière intervention
11 septembre 2004
-
on dirai ke taime pa tro les MFC (comme moi :) avec ton titre...
lol il est bien ton telnet continue
cs_Nebula
Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1 -
C'est pas tellement les MFC en tant que telles qui me gêne, c'est juste que je vois pas l'intérêt de dépendre de dlls parfois titanesques (je ne citerais que le cas de VB, meme si c'est pas des MFC) alors que tout ce dont on a besoin se trouve dans les dlls de windows... Mais çà n'engage que moi hein, pas frapper ;)

Krox, merci pour ta source, elle m'a beaucoup appris et je vais probablement faire un truc similaire pour le faciliter la vie :p En y incluant la création de contrôles communs toutefois, si çà t'intéresse je te l'enverrais ;)

Mon objectif maintenant est de recoder une appli que j'ai faite en Delphi (et bourrée de bugs car j'ai du bricoler avec l'API pour combler les lacunes de Delphi) en C, et y'a du boulot (PageControls, RichEdits et ListBox en OwnerDraw seront de la partie) :s

Envoyez vos dons (sous la forme de cachets d'aspirine) svp ;p
Anacr0x
Messages postés
515
Date d'inscription
dimanche 25 mai 2003
Statut
Membre
Dernière intervention
27 avril 2006
1 -
ben moi j'aimeré posé une tte petite question : en fait, j'ai un peu de mal a comprendre cette source (surtt kil y a plein de fonction ke je coné pa) et j'aimeré bi1 savoir kommen tu fait pour affiché dans la boite de dialogue la réponse que le serveur t'envoi
Anacr0x
Messages postés
515
Date d'inscription
dimanche 25 mai 2003
Statut
Membre
Dernière intervention
27 avril 2006
1 -
dsl, oublié ce ke je vien de dire, j'en é plus besoin, merci kan meme ;)
meech
Messages postés
209
Date d'inscription
vendredi 11 avril 2003
Statut
Membre
Dernière intervention
14 août 2007
-
mortel...

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.