Windows API tutorial that is specifically for C

Windows API tutorial that is specifically for C

Post by eggscrambler on Tue Aug 21, 2012 12:35 am
([msg=68870]see Windows API tutorial that is specifically for C[/msg])

Hey guys I have looked on Microsoft's website, but they have their tutorial directed at C++ instead of C. I have been looking for this for about 3 days, but no luck. Any help would be appreciated.
eggscrambler
New User
New User
 
Posts: 16
Joined: Thu Apr 28, 2011 11:30 pm
Blog: View Blog (0)


Re: Windows API tutorial that is specifically for C

Post by ghost107 on Sat Sep 01, 2012 5:02 pm
([msg=69087]see Re: Windows API tutorial that is specifically for C[/msg])

All windows API are in C, except for MFC, CLR, ATL, some say they are classes but if you look at the description they are structs.

So what do you want a basic windows creation tutorial, this is a translated version of my old tutorial which was in Romanian, which I wrote a few years back for a friend.

Introduction
The main function in windows is a little different from the traditional int main()(from the console programming), the function will look something like this(http://msdn.microsoft.com/en-us/library ... 85%29.aspx).
Code: Select all
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

Win main it is not really necessary you could just simply use int main() if you want.

Creating a Window
Many types (like dialogs, controls, and other visual objects) are actual windows and sub-windows. The windows are created by the API function CreateWindowEx, to create any kind of window, be it the main window, or a control.
Code: Select all
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInt, HINSTANCE hpInt, LPSTR lpLine, int nShow){
      //Creating a window
      CreateWindowEx(   
        WS_EX_CLIENTEDGE, // Window Type
        WC_DIALOG, //Class Name
        "MyWindow", // Window Title
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, // Window Proprieties
        0, // x Position on the Screen
        0, // y Position on the Screen
        width, // window Width
        height, //window Height
        NULL, // Parent window
        NULL,
        NULL, //Hint, handle to the previous window
        NULL
     );
         //add await time or the window will close really fast
   return 0;
}


Or it could be added in the WM_CREATE(will talk later into the window Procedure)

Creating Controllers
The window handle is an HWND(usually we call it hWnd), the function CreateWindowEx returns the window handle which it creates. Without the handle we can not send messages to the child windows(controls).
Code: Select all
HWND myDialogWindow = CreateWindowEx( arguments);


The code will look like(http://msdn.microsoft.com/en-us/library ... es_classes):
Code: Select all
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInt, HINSTANCE hpInt, LPSTR lpLine, int nShow){
      //Creating a window
      HWND hMainWindow = CreateWindowEx(   
        WS_EX_CLIENTEDGE, // Window Type
        WC_DIALOG, //Class Name
        "MyWindow", // Window Title
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, // Window Proprieties
        0, // x Position on the Screen
        0, // y Position on the Screen
        width, // window Width
        height, //window Height
        NULL, // Parent window
        NULL,
        NULL, //Hint, handle to the previous window
        NULL
     );
       //Creating a button
   HWND hButton1 = CreateWindowEx(
      0,
      "BUTTON",// the class name, there are many classes "LABLE", EDIT", etc
      "Buton",
      BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,         
      50,50,100,25,
      hMainWindow ,// handle to the main parent window
      NULL,NULL,NULL
   );

         //add await time or the window will close really fast
   return 0;
}


The Window Procedure
The Window Procedure receives every event that happens on the main window(for example it could be user events, pressing a button, etc). The window procedure is called by the system when an event on the window happens, and the window is informed with a message.
Code: Select all
LRESULT WINAPI proc_name(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)


For a procedure to be attached to a window it needs to instantiate a class of type WNDCLASSEX and registered with RegisterClassEx. The function PostQuitMessage informs the main loop to break, any window procedure must not always return 0.
Code: Select all
#include <windows.h>
//the window procedure
LRESULT WINAPI wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
   //if the message is WM_CLOSE
   if(message == WM_CLOSE) {
           // when pressing the X on the window it will send WM_CLOSE to the window procedure
      // with PostQuitMessage will exit the while loop
      PostQuitMessage(0);      
   }

   return 0;
}

//the entry point of the window
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
    WNDCLASSEX wc;  //the window class
    wc.cbSize        =  sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = wndProc;  //the window procedure
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hint;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "WindowClass"; //the class name
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    // registering the class
    if(!RegisterClassEx(&wc)){
         //error it can not register the class
    }

     // creating a window
    HWND hwnd = CreateWindowEx(      0, "WindowClass","A dialog window",
               WS_OVERLAPPEDWINDOW | WS_VISIBLE,
               400,100,200,200,
              NULL,NULL,NULL,NULL
     );

    //making the window visible, showing the window
    ShowWindow(hwnd, true);
     
    //updating the window
    UpdateWindow(hwnd);   

    //the window message loop
    MSG msg;
    while(GetMessage(&msg,NULL,0,0))  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
    }
    return 0;
}


Controllers types and how to use them
A good thing to know about controllers is that they are windows. As any other normal window they have a window procedure, window class, etc. which they are registered from the system. Anything you can do with a normal window you can do with a controller.

Messages:
Windows communicate using messages, when an event happens or when you want an control to do something, it will send a notification message. For standard controls the message will be WM_COMMAND and for common controls its WM_NOTIFY.

Messages can be send to a window using the API SendMessage with the use of GetDlgItem to access the data from that control, or you can use SendDlgItemMessage to do what SendMessage and GetDlgItem does.

The Edit Boxes
One of the most used controls are the windows environments is the edit control, that permits the user to insert, modify, copy,etc text.

We said earlier about the CreateWindowEx to create controls.
Code: Select all
#define IDC_EDIT   101 //used to identify a control, or you could use an enum

HWND hEdit = CreateWindowEx(
      0,
      "EDIT",// class name
      "Text Box",
      BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,         
      50,50,100,25,
      hwnd,
      (HMENU)IDC_EDIT, //the control identifier
      NULL,NULL
   );


Accessing the information on the in the edit box it is made using the functions GetDlgItemText,si SetDlgItemText, GetWindowText, SetWindowText:

Code: Select all
//hEdit is the control handle, and it can be accessed from anywhere
HWND  hEdit = GetDlgItem( hwnd, IDC_EDIT);
GetWindowText(hEdit,buffer,255);
SetWindowText(hEdit,"New Message");

//or
GetDlgItemText(hwnd, IDC_EDIT, buffer, 255)
SetDlgItemText(hwnd, IDC_TEXT, "This is a string");


Notification Messages
When someone presses a button, the button sends the notification codes in type of WM_COMMAND to the parent window. for example a button control sends a notification code under the IDC_BUTTON every time the user presses the button.

Code: Select all
#define IDC_BUTON   102 //used for identifying a button
CreateWindowEx(
      0,
      "BUTTON",// button class
      "Button",
      BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,         
      50,50,100,25,
      hwnd,
      (HMENU)IDC_BUTON
      ,NULL,NULL
   );

And in the Window procedure:
Code: Select all
LRESULT WINAPI wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
   //you can change the if into a switch
   if(message == WM_COMMAND){   
      switch(wParam){
   case IDC_BUTON:      
      MessageBox(hwnd,"Button Pressed","BTN WND",0);
      break;
   }
   return 0;
   }
}


Other Notifications:
WM_CREATE runs only once when the main window is created, in this notification you can create controls(Wrote above). WM_DESTROY same as WM_CREATE it runs once, when the window is destroyed, WM_PAINT it is called every time the function DispatchMessage is called.

WM_KEYDOWN and WM_KEYUP is called every time you press or release a keyboard key;
Code is from my Disertation Project
Code: Select all
switch(message) {
       case WM_KEYDOWN: // If we get a key down message, do stuff

         switch(wParam)
         {
            case VK_ESCAPE: // If they push ESC, close the app
               SendMessage(hwnd, WM_CLOSE, 0, 0);
                  break;

            case 'W':
            case VK_UP: // If they push up, move forward (Camera's +Z)
               gCamera->move(Camera::eForward, MoveSpeed);
                  break;

            case 'S':
            case VK_DOWN: // If they push down, move backward (Camera's -Z)
               gCamera->move(Camera::eBack, MoveSpeed);
                  break;

            case 'D':
            case VK_RIGHT: // If they push right, move right (Camera's +X)
               gCamera->move(Camera::eRight, MoveSpeed);
                  break;

            case 'A':
            case VK_LEFT: // If they push left, move left (Camera's -X)
               gCamera->move(Camera::eLeft, MoveSpeed);
                  break;

            case 'R':
               gCamera->reset(); // Recenter the camera
                  break;
         }
                  break;
}


WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, etc notifications are mouse events notifications or you could use WM_INPUT
Code: Select all
case WM_MOUSEMOVE:
    {
        int xPos = GET_X_PARAM(lParam); //X absolute position
        int yPos = GET_Y_PARAM(lParam); //Y absolute position
        // ...
        break;
    }
Last edited by ghost107 on Sat Sep 01, 2012 5:58 pm, edited 1 time in total.
ghost107
Poster
Poster
 
Posts: 142
Joined: Wed Jul 02, 2008 7:57 am
Blog: View Blog (0)


Re: Windows API tutorial that is specifically for C

Post by limdis on Sat Sep 01, 2012 5:17 pm
([msg=69089]see Re: Windows API tutorial that is specifically for C[/msg])

ghost107, outstanding +1.You should submit as an article. :geek:
"The quieter you become, the more you are able to hear..."
"Drink all the booze, hack all the things."
User avatar
limdis
Moderator
Moderator
 
Posts: 1433
Joined: Mon Jun 28, 2010 5:45 pm
Blog: View Blog (0)



Return to C and C++

Who is online

Users browsing this forum: No registered users and 0 guests