Visual C 6.0

The classic Windows programming is based on the C language and the direct use of the Windows API. This type of programming is described very clearly in Charles Petzold's book "Programming Windows". There is a reduced dependence on controls (other than the "basic" controls) and the IDE is not graphical in nature. The programs execute quickly and the dependencies are very few. The structure of the program is a header file, a C source file, and any resources used. The main program consists of two parts: the application code which is the creation portion and the main callback function which contains a switch statement for processing messages. This is where the main painting goes on if required. My purpose here is obviously not to teach C programming but to provide some source code for hobbyists who are creating their own projects. (See books by Kernighan & Ritchie and by Perry) If you are following along a book or a site that is teaching this type of programming, then this application might be useful to you.

What is a message? A message is the Windows operating system invoking your callback function via a pointer to it because some action, presumably by the user, has resulted in a need for your program to respond. This may be the most clearly exposed version of events programming that any of the frameworks reveal and the most clearly exposed subclassing capabilities that are offered.

Our example here is a spreadsheet with a fair number of capabilites but certainly no Excel, QuattroPro, or Lotus clone. So why bother? Well, for one thing it could be a good teaching tool for yourself. It also gives you a lightweight tool that you can program to satisfy your own functional needs. Whatever you want, it will be hard-coded and execute at blinding speeds. This application also contains some ways of saving data where you are in control of the format, and it is not all text either. I think this is far superior than having the framework do all the IO for you and you have not a clue as to what is going on.



SpreadLite





Now for the code. I will only excerpt a portion of the main application. The entire project file will be made available for download at some point.

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
 static TCHAR szAppName[] = TEXT ("SpreadLite") ;
 HWND hwnd ;
  //HWND hwndEdit ;
 MSG msg ;
 WNDCLASS wndclass ;
 wndclass.style = CS_HREDRAW | CS_VREDRAW ;
 wndclass.lpfnWndProc = WndProc ;
 wndclass.cbClsExtra = 0 ;
 wndclass.cbWndExtra = 0 ;
 wndclass.hInstance = hInstance ;
  //wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
 wndclass.hIcon = (HICON) LoadImage (0, "spreadlite.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE ) ;
 //wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON1)) ;
 //wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
 wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
 wndclass.lpszMenuName = NULL ; //szAppname
 wndclass.lpszClassName = szAppName ;
 if (!RegisterClass (&wndclass))
 {
  MessageBox (NULL, TEXT ("Program requires Windows NT!"), szAppName, MB_ICONERROR) ;
  return 0 ;
 }
 hwnd = CreateWindow (szAppName, TEXT ("SpreadLite"), WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;
 hInst = hInstance ;
 Myhwnd = hwnd;
 ShowWindow (hwnd, iCmdShow) ;
 UpdateWindow (hwnd) ;
 while (GetMessage (&msg, NULL, 0, 0))
 {
  if (hDlgPic == 0 || !IsDialogMessage (hDlgPic, &msg) || !IsDialogMessage (hDlgFindReplace, &msg))
  {
   TranslateMessage (&msg) ;
    DispatchMessage (&msg) ;
   }
  }
  return msg.wParam ;
}
//Main callback function with all the goodies************************
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 static int cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth, rowh, colw, rows, cols, iMaxHeight, numpaintlinesx, numpaintlinesy, iVertPosrow, iHorzPoscol ;
 HDC hdc ;
 int i, j, k, x, y;//, iVertPos, iHorzPos; //, iPaintBeg, iPaintEnd ;
 ///...
 //***Message Processing ******************
 switch (message)
 {
  case WM_CREATE:
   hdc = GetDC (hwnd) ;
   ///....