Thread: Creating A Window in C

  1. #1
    null pointer Structure's Avatar
    Join Date
    May 2019
    Posts
    338

    Post Creating A Window in C

    A Simple Window

    Code:
    #include <windows.h>
    
    const char g_szClassName[] = "myWindowClass";
    
    // Step 4: the Window Procedure
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch(msg)
        {
            case WM_CLOSE:
                DestroyWindow(hwnd);
            break;
            case WM_DESTROY:
                PostQuitMessage(0);
            break;
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX wc;
        HWND hwnd;
        MSG Msg;
    
        //Step 1: Registering the Window Class
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.lpfnWndProc   = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance;
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = g_szClassName;
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
        if(!RegisterClassEx(&wc))
        {
            MessageBox(NULL, "Window Registration Failed!", "Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
    
        // Step 2: Creating the Window
        hwnd = CreateWindowEx(
            WS_EX_CLIENTEDGE,
            g_szClassName,
            "The title of my window",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
            NULL, NULL, hInstance, NULL);
    
        if(hwnd == NULL)
        {
            MessageBox(NULL, "Window Creation Failed!", "Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
    
        ShowWindow(hwnd, nCmdShow);
        UpdateWindow(hwnd);
    
        // Step 3: The Message Loop
        while(GetMessage(&Msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        return Msg.wParam;
    }
    source: Tutorial: A Simple Window
    "without goto we would be wtf'd"

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    A more "complete" example:
    Code:
    /* winapp.c.in */
    /*
       Windows App template, in C.
      
       To compile (on Linux, using MinG64), substitute the @vars@ first (for example):
    
        $ sed "s/@appclass@/MyWinAppClass/;
               s/@uniqueid@/`uuidgen -r`/;
               s/@width@/640/;
               s/@height/480/" winapp.c.in > winapp.c
    
        Then:
    
        $ x86_64-w64-mingw32-gcc -O2 -D__SINGLE_INSTANCE__ -c -o winapp.o winapp.c
        $ x86_64-w64_mingw32-windres winapp.rc winappres.o
        $ x86_64-w64-mingw32-gcc -Wl,-subsystem=windows -o winapp.exe winapp.o winappres.o -lgdi32
     */
    #include <windows.h>
    
    LRESULT CALLBACK WindowMessageHandler(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpszCmdLine, int nCmdShow)
    {
      HWND hWnd;
      MSG msg;
      static const char *className = "@appclass@";
      WNDCLASS wc = {};
    
    /* __SINGLE_INSTANCE__ must be defined if you want only one
       instance of this windows running. */
    
    #ifdef __SINGLE_INSTANCE__
      /* Changed at compile time. */
      #define MUTEX_NAME "@uniqueid@"
    
      CreateMutex(NULL, TRUE, MUTEX_NAME);
    
      /* If named mutex already exists, exit. */
      if (GetLastError() != NO_ERROR)
        return 0;
    #endif
    
      wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
      wc.lpfnWndProc = WindowMessageHandler;
      wc.hInstance = hInstance;
      wc.hIcon = LoadIcon(hInstance, "WINAPP_ICON");  /* WINAPP_ICON defined in resource file. */
      wc.hCursor = LoadCursor(NULL, IDC_ARROW);
      wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
      wc.lpszClassName = className;
    
      RegisterClass(&wc);
    
      if ((hWnd = CreateWindowEx(
                    0,
                    className,
                    "@apptitle@",     /* Changed at compile time */
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    @width@, @height@,  /* Changed at compile time */
                    NULL,
                    NULL,
                    hInstance,
                    NULL
                  )) == NULL)
      {
        MessageBox(NULL, 
                   "Error creating window!", 
                   "Error", 
                   MB_OK | MB_ICONERROR);
        return 0;
      }
    
      UpdateWindow(hWnd);
      ShowWindow(hWnd, nCmdShow);
    
      while (GetMessage(&msg, NULL, 0, 0))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
    
      return msg.wParam;
    }
    
    /* Can be any value... 100 is a good one! */
    #define ID_STATIC1  100
    
    LRESULT CALLBACK WindowMessageHandler(HWND hWnd, 
                                          UINT uMsg, 
                                          WPARAM wParam, 
                                          LPARAM lParam)
    {
      RECT rc;
      HDC hDC;
      HWND hStaticWnd;
    
      switch (uMsg)
      {
        case WM_CREATE:
          /* Don't remember if this is the correct way! */
          GetClientRect(hWnd, &rc);
    
          /* This will not fail! 
             Don't remember if SS_SIMPLE has VCENTER and HCENTER attribs. */
          hStaticWnd = CreateWindowEx(
                          0,
                          "static",
                          "Hello, Windows!",
                          WS_VISIBLE | WS_CHILD | SS_SIMPLE,
                          rc.left, rc.top,
                          rc.right - rc.left, rc.bottom - rc.top,
                          hWnd,
                          (HMENU)ID_STATIC1,
                          ((LPCREATESTRUCT)lParam)->hInstance,
                          NULL
                        );
    
          /* Set Windows default font to child window */
          SendMessage( hStaticWnd, 
                       WM_SETFONT, 
                       (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 
                       TRUE );
    
          break;
    
        /* Don't need to handle WM_CLOSE here! */
    
        case WM_DESTROY:
          PostQuitMessage(0);
          break;
    
        default:
          return DefWindowProc(hWnd, uMsg, wParam, lParam);
      }
    
      return 0;
    }
    Code:
    # Makefile
    CC = x86_64-w64-mingw32-gcc
    RC = x86_64-w64-mingw32-windres
    CFLAGS = -O2 -mtune=native -D__SINGLE_INSTANCE__
    
    winapp.exe: winapp.o winappres.o
        $(CC) -o $@ $^ -Wl,-subsystem=windows -lgdi32 
    
    winapp.o: winapp.c
    
    winappres.o: winapp.rc
        $(RC) $< $@
    
    winapp.c: winapp.c.in
        sed "s/@uniqueid@/$$(uuidgen -r)/;s/@appclass@/MyAppClass/;s/@width@/640/;s/@height@/480/" winapp.c.in > winapp.c
    
    .PHONY: clean
    
    clean:
        -rm *.c *.o *.exe
    Code:
    /* winapp.rc */
    CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "winapp.manifest"
    WINAPP_ICON ICON "winapp.ico"
    Code:
    <!-- winapp.manifest -->
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
          <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
          </requestedPrivileges>
        </security>
      </trustInfo>
      <dependency>
        <dependentAssembly>
          <assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0"
                            processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
        </dependentAssembly>
      </dependency>
    </assembly>
    The winapp.ico is an small icon file (choose yours)... 32x32 pixels is enough

    Just call 'make' (on Linux, x86-64, with MinGW-64 installed)...
    Last edited by flp1969; 09-04-2019 at 04:22 PM.

  3. #3
    null pointer Structure's Avatar
    Join Date
    May 2019
    Posts
    338

    Thumbs up

    more "complete"
    I was trying to give the simplest example.

    I would suggest using a library to create the window as a standard window is much slower loading.

    "without goto we would be wtf'd"

  4. #4
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    Quote Originally Posted by Structure View Post
    I would suggest using a library to create the window as a standard window is much slower loading.
    What makes you think a library is faster than direct WinAPI calls? Whatever the library you're using, ultimately is has to make the same (and, most of the time, many more) calls to the operating system. If anything, a "standard window" should be faster and produce the smallest binary.
    Last edited by GReaper; 09-14-2019 at 09:48 AM.
    Devoted my life to programming...

  5. #5
    null pointer Structure's Avatar
    Join Date
    May 2019
    Posts
    338
    What makes you think a library is faster than direct WinAPI calls?
    Compare a window created using the above examples, to a window created using:
    GLFW - An OpenGL library

    Compiling and Loading are faster imo using the library.

    a "standard window" should be faster and produce the smallest binary
    in theory.
    "without goto we would be wtf'd"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating a child window in a parent window
    By vopo in forum Windows Programming
    Replies: 8
    Last Post: 10-06-2007, 04:15 PM
  2. help with creating window
    By Darkinyuasha1 in forum Windows Programming
    Replies: 6
    Last Post: 06-12-2007, 06:51 PM
  3. Creating a Window
    By ILoveVectors in forum Windows Programming
    Replies: 4
    Last Post: 07-13-2005, 09:46 PM
  4. Creating a New Window
    By tyouk in forum Windows Programming
    Replies: 3
    Last Post: 01-02-2005, 09:39 PM
  5. Problem with creating new window, from another window
    By Garfield in forum Windows Programming
    Replies: 6
    Last Post: 01-11-2004, 02:10 PM

Tags for this Thread