Frederick2 189 Posting Whiz

I also feel raw code style programming is probably best for me as well instead of using resource editors that are provided in VStudio.

Absolutely! Using the Windows Dialog Engine to learn Windows programming is IMNSHO a big mistake.

Recently I posted some beginning Api Sdk style code plus explanations here...

http://www.jose.it-berater.org/smfforum/index.php?topic=3389.0

Program Example 37 starts GUI stuff. Before that is general C/C++ stuff.

You know, with Dev-CPP and all other development suites, you can't just code Win32 Api Sdk code in a blank code window and hit the compile button. You have to go through the various setup screens accessable from the file menu >> Create New Project option. When you choose the option to create a GUI program then the compiler options will be set correctly for you. I'm wondering if that is/was your problem. Anyway, glad its working for you now.

Frederick2 189 Posting Whiz

I did to your code as William suggested and changed your SendMessage(GET_TEXT) to GetWindowText() calls. Much easier.

Also, I removed your two global variables. The szClassName only needs to be defined in the proc where the WndClass is registered. Also, there are a half dozen ways to get hInstance anywhere in your code you need it. I used GetModuleHandle() in your WM_CREATE handler. Also, no need to define specific handles for the HWND button and edit box. They go out of scope right after the WM_CREATE handler anyway.

here is you modified code

#include <windows.h>
#include <stdio.h>

// Define custom messages
#define IDM_BUTTON 1
#define IDM_TEXT   2

// Functions List //
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    char szClassName[] = "myWindowClass";
    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 = szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    // if registration of main class fails
    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,
        szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
        NULL, NULL, hInstance, NULL);
    

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    } …
Frederick2 189 Posting Whiz

I just recently posted some tutorials here...

http://www.jose.it-berater.org/smfforum/index.php?topic=3389.0

Lot of stuff having to do with pointers, message crackers, etc.

If you are into graphics at the Api level you should probably think about Charles Petzold's Programming Windows book. He is heavy into graphics. I can't really speak to other class framework wrappers on GDI or otherwise because I'm not into that.

zobadof commented: Thanks! +0
Frederick2 189 Posting Whiz

The question has me intrigued too. I've worked with the mouse a lot both in Windows and DOS and it never occurred to me that there might be a way to programatically move the mouse. In other words - mouse output. When you look it up in MSDN there's piles of info on mouse input, but none on mouse output. The thought occurred to me to PostMessage() a WM_MOUSEMOVE message filling the WPARAM and LPARAM with the necessary data as to where you want to move the mouse cursor, but I doubt if that would work. Its designed for mouse input. I didn't try it myself.

Frederick2 189 Posting Whiz

nor are there any native MS-DOS assembly language system calls that support the mouse.

The int 33h interrupts were used for that, but I doubt the user is interested in those. In any case, I don't believe I've ever tried to move the mouse cursor. Usually, one wants to find out where it is.

By the user's question, I'm not sure just what is meant by...

...without any help from the library,header file or built in function...

In terms of what can be done in C/C++ without the use of libraries - darn little. You could add 2 and 2 I suppose - but you couldn't output the result. I suppose if you wanted you could find the result - 4, using a debugger!

Frederick2 189 Posting Whiz

I see you are using Dev-C++ too. I missed that at first. I'm with William. Don't know what the problem is. Maybe try putting the project together again.

Frederick2 189 Posting Whiz

Hi Cody!

I didn't run your 2nd program but was able to compile the first one you seem to be having troubles with. I used the Dev-C++ development suite. However, I had to comment out this line because I didn't have the icon file which you apparently have...

//IDI_MYICON ICON "menu_one.ico"

That would have been in your resource script which I named resource.rc for when I built your program. What development system are you using? I have a number of others, but just tried Dev-C++ because that's the quickest to put a little project together.

Here's another example for you of one of my learning programs...

//Main.c
#include <windows.h>
#include <commdlg.h>
#include <string.h>
#include "Form8.h"

typedef struct WindowsEventArguments
{
 HWND hWnd;
 WPARAM wParam;
 LPARAM lParam;
 HINSTANCE hIns;
}WndEventArgs,*lpWndEventArgs;


BOOL CALLBACK ModalDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
 char szName[64],szText[64];
 HWND hwndEdit;
 UINT nID;

 switch(message)
 {
  case WM_INITDIALOG:
    hwndEdit=GetDlgItem(hwndDlg,IDC_NAME);
    SetFocus(hwndEdit);
    return FALSE;
  case WM_COMMAND:
    nID = LOWORD(wParam);
    switch(nID)
    {
     case IDOK:
       hwndEdit=GetDlgItem(hwndDlg, IDC_NAME);
       GetWindowText(hwndEdit,szText,64);
       strcpy(szName,"Hello, ");
       strcat(szName,szText);
       strcat(szName,"!");
       MessageBox(hwndDlg,szName,"Form8",MB_OK);
     case IDCANCEL:
       EndDialog(hwndDlg, nID);
       break;
     default:
       break;
    }
    return TRUE;
  default:
    return FALSE;
 }
}


long WndProc_OnCreate(lpWndEventArgs Wea)
{
 HWND hTextBox,hButton;
 DWORD dwStyle;

 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 dwStyle=WS_CHILD|WS_VISIBLE|WS_BORDER;
 hTextBox=CreateWindow("edit","",dwStyle,10,30,370,20,Wea->hWnd,(HMENU)IDC_EDITBOX1,Wea->hIns,0);
 hButton=CreateWindow("button","Exit",WS_CHILD|WS_VISIBLE,168,75,60,25,Wea->hWnd,(HMENU)IDC_BUTTON,Wea->hIns,0);

 return 0;
}


void WndProc_OnCommand_OnOpen(lpWndEventArgs Wea)
{
 static char szFilter[]="C Files (*.C),CPP Files (*.cpp)\0*.c;*.cpp\0\0";
 static char szTitleName[_MAX_FNAME+_MAX_EXT];
 static szFileName[_MAX_PATH];
 char lpszBuffer[128];
 OPENFILENAME ofn;
 
 GetCurrentDirectory(128,lpszBuffer);
 memset(&ofn,'\0',sizeof(OPENFILENAME));
 ofn.lStructSize=sizeof(OPENFILENAME);
 ofn.lpstrFilter = szFilter;
 ofn.nMaxFile=_MAX_PATH;
 ofn.nMaxFileTitle=_MAX_FNAME+_MAX_EXT;
 ofn.lpstrInitialDir = lpszBuffer;
 ofn.lpstrDefExt = "Sdb";
 ofn.hInstance=Wea->hIns;
 ofn.hwndOwner = Wea->hWnd;
 ofn.Flags=OFN_HIDEREADONLY | OFN_CREATEPROMPT;
 ofn.lpstrFile=szFileName;
 ofn.lpstrFileTitle=szTitleName;
 GetOpenFileName(&ofn);
 SetWindowText(GetDlgItem(Wea->hWnd,IDC_EDITBOX1),ofn.lpstrFile);

 return; …
Frederick2 189 Posting Whiz

Here's all of it...

#ifndef _FILE_DEFINED
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif
Frederick2 189 Posting Whiz

I'm pretty sure its line 273 that is causing the problem.

(The Microsoft documentation is right. There is something wrong in your code. But how can anyone help with the limited information you provided?)

Frederick2 189 Posting Whiz

i think WinApi like MFC is old and obsolete!

If that's the case how come new books are being written about both? First is Jeffrey Richter's 2007 book on the Win32 Api and 2nd is Ivor Horton's C++ book (2008) which still covers MFC?

http://www.amazon.com/Windows-via-Pro-Jeffrey-Richter/dp/0735624240/ref=sr_1_5?ie=UTF8&s=books&qid=1259253414&sr=8-5

http://www.amazon.com/Ivor-Hortons-Beginning-Visual-2008/dp/0470225904/ref=sr_1_1?ie=UTF8&s=books&qid=1259253556&sr=1-1

Frederick2 189 Posting Whiz

Anything you use other than the Win32 Api for Windows programming involves your use of the Win32 Api through an 'abstraction layer'. That abstraction layer might be MFC, it might be .NET. It might be wxWidgets or QT. In other words, you are making a trade off in the hope of gaining more from the trade off than you are losing by making it.

So you have to examine your personal situation and look at what you want to do. If what you want to do can easily be done through some higher level interface to the Win32 Api, or if it would be good to have the solution work in Linux/Unix, then the Win32 Api might not be the way to go. On the other hand, if its a complicated non-standard GUI and size/speed are important, the Win32 Api might be best.

Your own personal inclinations matter too. If you like the Win32 Api or want to learn to program against it then I'd factor that in. On the other hand, if you really like some other toolkit and are just thinking of learning the Win32 Api like taking medicine or something, then it might not work for you.

Frederick2 189 Posting Whiz

For PC desktop programming I use PowerBASIC from www.powerbasic.com.

For Windows CE I use C++, mostly because I don't have much choice. For both languages I use pointers extensively; both in PowerBASIC and C++. They are critical; however, until you become fairly advanced their need pretty much is hard to understand.

My personal preference in programming is to write low level code that is fast and small. Both PowerBASIC and C/C++ allow me to do that. I code exactly the same in both languages and I use the Win32 Api directly. If I want to put text in an edit control in a GUI app in C++ it looks like this...

char szBuffer[64];
strcpy(szBuffer,"Some Text To Go In A Text Box.");
SetWindowText(hWnd, szBuffer);

in PowerBASIC it looks like this...

Local szBuffer As Asciiz*64
szBuffer="Some Text To Go In A Text Box."
SetWindowText(hWnd, szBuffer)

Not much difference. That is the advantage of coding to the Win32 Api directly. Of course, if you are interested in Linux/Unix the Win32 Api won't do you much good.

C++ is a really neat and interesting language. However, you really need to be patient in waiting for results. It is very hard to learn, in my opinion. I suspect a lot of folks give up before achieving their goals. In that sense I think many folks here would be better off with some language that gives quicker results such as various dialects of …

Frederick2 189 Posting Whiz

You can write text strings to any window for which you have its hWnd with TextOut() or DrawText(). For edit controls, i.e., text boxes, you put text in them with SetWindowText()....

void MessageHandlingProcedure(HWND hWnd)
{
 char szBuffer[]="Some Text To Go In A Text Box";
 SetWindowText(hWnd, szBuffer);
}

If you use SetWindowText() with an ordinary top level window that has a title bar, the text will go in the Window Caption. Various windows respond differently to the call. Hope this helps. If you are trying to learn Win32 I'd recommend you get a book.

Frederick2 189 Posting Whiz

I'll tell you my opinion with the stress on OPINION. There is no easy way out. That's what everyone is looking for.

MFC will make it easier (3 months later). UMMM. This is getting confusing. UMMM. Maybe .NET will make it easier (6 months later and still 4 gigabytes of help docs to get through). UMMM. This is pretty confusing...

SomeObj.YetAnotherObj.ThenThisObj.ButDon'tForGetThisObj.ContainedInThisWorkSpace.AndNowAConrtainer....

But I'm willing to try anything but the basic Windows Api. Maybe Win32++...

Somebody please explain to me exactly how you can take a complex multitasking, multithreaded, multiwindowing system such as Windows, then overlay on top of that a complex object oriented layer as only C++ is capable of providing with its abstract base classes, inheritance chains, so on and so forth, and end up with something a beginner is supposed to understand. And the beginners are being told these other routes are easier than learning the basic Windows Api. That's the part that gets me.

Frederick2 189 Posting Whiz

AdRock,

Post some code in code tags. I don't think anybody wants to look at what you posted. Preferably short. Can you get a Hello, Woirld to compile in Linux?

Frederick2 189 Posting Whiz

Sometimes when you look at a whole long list like that it seems overwhelming. But instead of being overwhelmed by looking at the whole list, why not start with one very small piece at a time. The first function is this...

extern bool isUppercase( char c );

To write the function all you need to know are the ASCIIZ codes. You've certainly seen them before. Some are lower case and others are uppercase. That ought to suggest a starting point to you.

Frederick2 189 Posting Whiz

Like, what would that pointer, point to then? - if I call it's value in the second program.

More than likely some address not valid in the second program. If you want to try it go ahead - it shouldn't be that hard to do. I'm telling you what I am from my study of these things, plus I've seen this topic come up occasionally in other forums. If somebody else knows better, please jump in and correct me. My understanding of this issue is that Windows completely virtualizes hardware, and only within the deepest recesses (and not available to us) of the kernel is the actual mapping of the various processes's virtual addresses to physical hardware addresses.

Frederick2 189 Posting Whiz

I've been having some thought, like, if I run a program, and I'm exporting a pointer to a variable "a" to a file, and I reads that information with another program, wouldn't the second program be able to modify "a" in the first program using that pointer? - Like the memory address is the same right?

Any addresses you obtain are not real addresses but rather virtual addresses. In terms of real hardware addresses, i.e., physical addresses, only Windows itself deals with them. It isn't like back in the old DOS world where you could actually deal with hardware.

There are ways to share data between processes, but writing a virtual address to a file and reading it with another program isn't one of them.

Frederick2 189 Posting Whiz

Your declaration of destination only causes the compiler to allocate four bytes (32 bit OS) for the char* itself. In terms of memory at which it 'points', you need to allocate that with new, malloc, GlobalAlloc(), HeapAlloc(), whatever.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void strcpy2(const char* source, char* dest)
{	 
 while (*source != 0)
 {
   *dest = *source; 
   dest++;
   source++;
 }
 *dest = 0;
}


int main()
{	
 char* source = "Hello world";
 char* destination=NULL;
 
 destination=(char*)malloc(strlen(source)+1);
 if(destination)
 {
    strcpy2(source, destination);
    puts(source);
    puts(destination);
    free(destination); 
    system("pause");
 }   
 
 return 0;
}

The other alternative is to declare an arbitrarily sized character array to serve as a buffer into which you can copy the string. If you absolutely know what the upper possible bound of what you are copying is, then its possible to do that. For example, if you knew the character string you were copying couldn't be over 63 characters, you could do this...

char szStringBuffer[64];
if(strlen(source)<64)
   strcpy2(source, szStringBuffer);
else
   puts("Buffer Not Big Enough!!!");
Frederick2 189 Posting Whiz

You havn't allocated any memory at destination into which you can copy what is at source, so you are corrupting your data segment.

Frederick2 189 Posting Whiz

There are a small number of us that write major Windows applications in various languages using almost exclusively the Win32 Api.

All programmers have their own biases, favorite way of doing things, etc. My favorite way of doing things most certainly doesn't suit everybody, but I've got to tell you, I find using the Win32Api directly for writting Windows applications to be optimal for me. I state this after having spent many years doing it all sorts of other ways, e.g., VB1 - 6, VB or C#.NET, MFC, etc.

What I found amusing about your post is your conception of writing programs against the Win32 Api as some kind of unusual and hard to imagine bizarre thing. It most certainly isn't.

What I think the reality is, is that a great many folks learn C++ now and start out writing console programs, then move on to writing GUI applications whose underlying foundation is the Win32 Api but this fact is all but hidden from them due to their passive acceptance of GUI libraries that completely hide the underlying Apis on which it is based. This process appears to me to be so far advanced at this point that many using GUI application frameworks aren't even aware that Windows doesn't require them. Period.

The other lamentable fact I have noticed in C++ and other languages is an over reliance on Windows Dialog Engine created windows. What inevitably seems to happen is that folks start trying to use …

Frederick2 189 Posting Whiz

Another angle pokerDemon is that you are going to have to decide which is more important for you, i.e., learning C++ or learning to code some kind of poker game. If what's most important is being able to code a poker game, and C++ just happens to be the language somebody told you might be a possible choice, then maybe you ought to choose an easier language to use instead of C++. Fact is, the 'paying your dues' part is probably a lot higher in C++ than with other languages that don't even use pointers.

On the other hand, if its really important to you to learn C++ and you just used the poker thing as a possible example of something to start, then I'm afraid you are just going to have to bite the bullet and pay your dues if you want admittance.

Oh, and that thing about reading graphical numbers on your computer screen...

The graphics you see are just a rendered version of character strings that are existing in the programs data buffers. And the character strings are accessable through guess what?

Yep! You guessed it!

Pointers!

Frederick2 189 Posting Whiz

It wouldn't hurt to be clearer in your question then. To add additional text to a text box (multiline or otherwise), you need to retrieve the text already in the text box into a string variable/buffer within your program using GetWindowText() or some such, then concatenate your additional text onto it, then finally replace the entirety of the original text in the text box with the new.

Frederick2 189 Posting Whiz

The edit box has to be created with the appropriate style to act as a multi-line text box. Look up the styles - off the top of my head I just don't have them memorized. But if the right style wasn't used at creation time - it just ain't gonna ever be a multi-line edit box.

added later - from Api CreateWindow() docs...

ES_MULTILINE Designates a multiline edit control. The default is single-line edit control.

Here would be what a CreateWindowEx() call to create such an edit control would look like...

hEdit=
CreateWindowEx
(
 WS_EX_CLIENTEDGE,
 "edit",
 "",
 WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|ES_MULTILINE|WS_VSCROLL,
 60,80,620,24,
 hWnd,
 (HMENU)IDC_EDIT,
 ghInst,
 0
);
Frederick2 189 Posting Whiz

Seriously though, I had looked at wxWidgets about a year or two ago when I was snooping around with Linux coding. I had downloaded a wxWidgets demo of some simple Windows programs that just gave examples of basic windows controls, etc. The exes were quite large, as I recall. I didn't like that - I mean megabyte type stuff just for simple windows programs. That kind of turned me off. I do like the new CodeBlocks dev envr though - have to say that. And it works in Windows just like in Linux.

I never found anything in the Linux world anywhere near as elegant as the Windows Api. If I had the time & inclination I'd be more inclined to work directly with X - which I kind of liked. For relatively easy coding Gtk+ works good but its as ugly as sin - IMHO.

IWantToMakeAWindow();
IWantToPutAButtonOnTheWindow();
IWantToShowTheWindow();
IfSomeBodyClicksMyButtonSendMeANotification();
etc!!!!!!!

Frederick2 189 Posting Whiz

I would recomment you learn wxWidgets...

And what do you think the life expectancy of that body of knowledge will be Ancient Dragon?

The Win Api has been around in a form very similiar to what it is now since 1985. That's 24 years (I counted 'em). In those 24 years various class frameworks/programming paradigms have come & gone, e.g., VB1-6, MFC, etc. Win32 Api rules! :)

Frederick2 189 Posting Whiz

debasishgang7,

I don't like any of those things you don't like either debasishgang7. I deplore MFC, .NET, any class framework really. However, those things are for folks who want to take the easy way out. Its harder to write Windows programs without a class framework, at least at first. However, in the long run you are better off without them (IMNSHO). Windows programs (GUI) can be written using the Win32 Api. There are thousands of wonderful functions you can use and they are all very well documented. You can created windows with them, put buttons, textboxes, grids, custom controls, you name it, in those windows. The programs will run faster than any of those built with class frameworks and be 10 to a hundred times smaller. However, you have to learn how to do it and its a fairly steep climb. I'd start by getting a copy of Charles Petzold's Windows Programming book.

Frederick2 189 Posting Whiz

Sorry but i must say that's completly wrong.

I see nothing wrong with...

system("PAUSE");

In fact, the default c++ code Dev-C++ produces from its default console template uses it. Are you saying the folks who wrote the Dev-C++ IDE don't know what they are doing?

Personally, I usually don't use a lot of the default C++ headers in my console programs and use the C ones instead. I usually hold the screen open with getchar() from stdio.h.

Frederick2 189 Posting Whiz

Hi Again Ripture!

The answer to your question about putting buttons and textboxes on the program's main window can be seen in my procedure fnWndProc_OnCreate() in the above code. I'll reproduce it here...

long fnWndProc_OnCreate(lpWndEventArgs Wea){ HWND hTextBox,hButton; DWORD dwStyle;  Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance; dwStyle=WS_CHILD|WS_VISIBLE|WS_BORDER; hTextBox=CreateWindow(_T("edit"),_T(""),dwStyle,10,30,370,20,Wea->hWnd,(HMENU)IDC_EDITBOX1,Wea->hIns,0); hButton=CreateWindow(_T("button"),_T("Exit"),WS_CHILD|WS_VISIBLE,168,75,60,25,Wea->hWnd,(HMENU)IDC_BUTTON,Wea->hIns,0);  return 0;}

One of the 1st messages a window receives is the WM_CREATE message. This message occurs at the point of the CreateWindow() call in WinMain(). In fact, that CreateWindow() call in WinMain() does not return until the WM_CREATE message returns in the Window Procedure. It is in the WM_CREATE processing code (fnWndProc_OnCreate() above) where I usually put additional CreateWindow() calls that create the child window controls, ie, edit boxes, buttons, listboxes, grids, etc., that decorate the main window of the app. These child window controls have their own classname such as "button", "edit", etc. You can see the CreateWindow() calls above that created the edit box and button on my program's main form/dialog/window.

added later - for some reason unfanthomable to me code tags don't seem to be working. i've tried to fix the above cat's breakfast five times to no avail. sorry.

Frederick2 189 Posting Whiz

Wooh, I have to say after looking at the second code you posted, I have no idea where to start looking to understand it. When all you've done is some petty low-level C++ stuff just dealing with primitives and classes etc, trying to understand all of the intricacies of the windows API is fairly daunting.

I'm not trying to go too far with this, I just wanted to see if I could manage to make something extremely basic but usable as an interface with these simple programs I write.

Hi Ripture!

Glad to hear you are on the right track. I wasn't sure what was wrong with your code but I suspected the problem might be elsewhere in other code, that's why I posted a full example I was pretty sure would compile cleanly for you. Most problems with menus & dialogs in resource files stem from coding errors in the main program that tries to load the resource; particularly the naming of files and the .lpszMenuName field in the WNDCLASSEX struct.

What's confusing you in the second app I posted is my method (which I learned from Douglas Boling who writes Windows CE books - and he ascribes the technique to Ray Duncan where he learned it) of attaching the functions that handle Windows messages to the messages themselves that are coming through the program's Window Procedure. The setup involves C function pointers. Its the slickest way I've ever found to modularize my code.

Windows Api …

Frederick2 189 Posting Whiz

The above code was one of my early 'template' apps. When you do Win32 Sdk programming as I do, over time you amass quite a few template 'starter' apps to get you going when you want to create a new project. Since my coding style has changed some over the years, a lot of my older template apps don't really reflect the way I do things now - especially in regard to the whole UNICODE thing - which I've finally come to terms with and have 'accepted'. Anyway, I just redid this app in my present style. Basically, it shows the things you are trying to learn. Below I'll post it. I changed the names of the files some. This template is now Form2A. I name all my templates like this...

Form1, Form2, Form3, .... Form30, etc.

This evolved from my extensive VB background in my former pre .NET life. Since I've got so many of these when I redo them in my presemt style I append an 'A' to them.

//Form2A.h
#define IDC_STATIC        -1
#define IDR_MAIN_MENU   1240
#define IDM_OPEN        1250
#define IDM_SAVE        1252
#define IDM_EXIT        1254
#define IDM_HELP        1260
#define IDM_ABOUT       1262
#define IDC_NAME        1300
#define IDD_ABOUT       1400
#define IDC_EDITBOX1    1500
#define IDC_BUTTON      1510


typedef struct    WindowsEventArguments               
{
 HWND             hWnd;                               
 WPARAM           wParam;                             
 LPARAM           lParam;                             
 HINSTANCE        hIns;                               
}WndEventArgs, *lpWndEventArgs;


struct EVENTHANDLER
{
 unsigned int    Code;
 long            (*fnPtr)(lpWndEventArgs);
};
//Form2A.rc
#include <windows.h>
#include <tchar.h>
#include "Form2A.h"

IDR_MAIN_MENU MENU
{
 POPUP _T("&File")
 {
  MENUITEM _T("&Open..."),          IDM_OPEN
  MENUITEM _T("&Save..."), …
Frederick2 189 Posting Whiz

This issue is the biggest problem I have in coding because it takes me a long time to develop the software, and the life expectancy of any specific configuration of OS and hardware is rather low. I'm certainly open to anything new that comes along, but I'm not hopeful.

Frederick2 189 Posting Whiz

Hi Ripture,

Here is some code from Dev-C++ that uses a resource file I dug up from a few years back. I just rebuilt the project as C++ (it was C) and it works. The code also has a menu in it where you can go to the File menu & choose Open and the Open File Dialog Box will present itself. On the Help menu a dialog box from a resource file (.rc) is created. Hope it helps you. The main source is Main.cpp, the project name is Form11, the header is Form11.h and the rc file is Form11.rc. Create the Form11 project and put all the files in that dir. Then include them in the project, that is, Main.cpp, Form11.h and Form11.rc.

//Form11.h
#define IDC_STATIC      -1
#define IDR_MAIN_MENU   1240
#define IDM_OPEN        1250
#define IDM_SAVE        1252
#define IDM_EXIT        1254
#define IDM_HELP        1260
#define IDM_ABOUT       1262
#define IDC_NAME        1300
#define IDD_ABOUT       1400
#define IDC_EDITBOX1    1500
#define IDC_BUTTON      1510
//Resource Script
#include <windows.h>
#include "Form11.h"

IDR_MAIN_MENU MENU
{
 POPUP "&File"
 {
  MENUITEM "&Open...",          IDM_OPEN
  MENUITEM "&Save...",          IDM_SAVE
  MENUITEM SEPARATOR
  MENUITEM "E&xit",             IDM_EXIT
 }
 POPUP "&Help"
 {
  MENUITEM "&Help...",          IDM_HELP
  MENUITEM "&About Form8...",   IDM_ABOUT
 }
}

IDD_ABOUT DIALOG DISCARDABLE 30,60,180,36
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Identify Your Sorry Self!"
FONT 8, "MS Sans Serif"
BEGIN
  DEFPUSHBUTTON  "OK",IDOK,120,20,40,14
  PUSHBUTTON     "Cancel",IDCANCEL,75,20,40,14
  LTEXT          "Enter Your Name",IDC_STATIC,7,4,60,8
  EDITTEXT       IDC_NAME,65,4,100,12,ES_AUTOHSCROLL
END
#include <windows.h>
#include <commdlg.h>
#include <string.h>
#include "Form11.h"

typedef struct WindowsEventArguments
{
 HWND hWnd;
 WPARAM wParam;
 LPARAM lParam; …
Frederick2 189 Posting Whiz

Thanks for the info opcode & Ancient Dragon. I'm slowly putting the pieces together. This is pretty embarissing to me actually that I didn't know C++ had a String class. For a number of years I'd been perfecting my own String class figurring when I finally got it right I'd be in good shape with C++. Only to find there is one. What had me confused were the constant references to 'string' or <string> as being 'The' C++ string class, and every time I'd see that I'd think, "Heck, all that is are all those strcpy(), strcat() wrappers around the asm byte blaster string primitives that hardly merits the name of a 'Class'.

I get the picture now!

Frederick2 189 Posting Whiz

Not really. The most useful and commonly used databases are known as 'relational databases' and the good thing about them is that they mostly follow the rules set down many years ago by all the big players in databases and those rules are ODBC. So, if you learn how to write a program that conncts to any particular one of these databases, then, chances are good that your program can switch to using another database with little or no modifications. For example, in my programming with Microsoft Access which I mentioned above, when I tested it with SQL Server, there were fairly minimal changes needing to be done to work wuth the latter. So what you need to do is get yourself some database to work with, learn a little SQL ( Structured Query Language ) , then see how you want to connect through C++ code if that's the way you want to go.

Frederick2 189 Posting Whiz

MS-Access is a great database for small projects. Its ok for 1-3 simultaneous connections. Anything more and Access can generate file corruptions.

Yea, that's the thing. I created our (my organization, i.e., where I work) main database about 5 years ago and it contains pretty many tables and lots of relationships. There are about 5 or 6 main users through my various front end programs; however, chances are small more than 2 or 3 would ever be performing transactions on it simultaneously. About two years ago another coder here added access to it through Asp.net for a particular type of database transaction that happens fairly infrequently - perhaps a couple per week. I consider this living dangerously; however, so far no problems.

I've mentioned many times that I thought we would be better served by mocving to Sql Server (we have several), but the way everybody looks at it is that if it ain't broke - don't fix it! Before I setup the Access database we had a miserable system we'd paid millions for which didn't hardly work and nobody understood. With Access everybody likes it and doesn't want to change. So we keep things pretty well backed up and hope for the best.

Frederick2 189 Posting Whiz

MS Access was my first experience with relational databases about 15 years ago. It always amazes me to see so many people knock it for one reason or another (its not free like MySql, its not as robust as Sql Server, on and on). I've had nothing but good experiences with it, and it serves as an excellent tool to get started learning about databases, structured query language, relationships in data, etc.

So the thing to do would be to get your tables and relationships set up, and once that's done then look into a user interface front end to the database. Heck, the various GUI tools in Access itself might be enough. However, if not, front ends can be coded in any number of languages. C++ probably isn't the best choice, but its certainly doable. Historically I believe, most folks used Visual Basic for database front ends. Its simply easier.

Frederick2 189 Posting Whiz

Hey Taphofyle!

You're into database programming with that. Unless you are a coding guru, I'd recommend not writing your own file structures, i.e., file access/retrieval, for something like that. If you haven't studied database programming yet, I'd recommend you do so. In C++ your choices are connecting with databases through higher level OOP front ends such as ADO (ActiveX Data Objects), or the lower level ODBC (Open DataBase Connectivity) route. I personally do all my database work through low level ODBC. I have some examples posted here...

http://www.jose.it-berater.org/smfforum/index.php?board=378.0

Ancient Dragon commented: Good suggestion :) +36
Frederick2 189 Posting Whiz

Both text (ascii or unicode) and binary data can be easily stored in either flat files you open, close & manage yourself, or in regular databases which would involve dealing with its Api, so the question doesn't really have anything to do with size. What does your data look like specifically, e.g., is it names and addresses, what?

Frederick2 189 Posting Whiz

Its not completely clear from your post whether you want to go the relational database route or the simple flat file route. That's basically the first question you must decide. The techniques involved vary considerable depending on which way you go.

Frederick2 189 Posting Whiz

Thanks for the info AncientDragon. I'm slowly figuring it out. I had a feeling I was juxtoposing things that might not be related, that is, MFC & C++ generic String Class Concepts. Just tonight I tried my above program (slight modification of one I found at Wikipedia) with VC++9 and optimized for size it compiles down to 8 or 9 K.

What's really blowing my mind though in terms of just the unbelievable intricacies of all this...

...in the above blurb of code (post #3 in this thread), if <string> is replaced with <string.h>, the whole thing flies apart! If its not asking too much, I'd love an explanation of that one.

Frederick2 189 Posting Whiz

Thanks for the idea Sfuo. I've got Dev-Cpp too and did a little research at Wikipedia...

http://en.wikipedia.org/wiki/String_(C%2B%2B)

and found a program I modified to this...

#include <stdio.h>
#include <string>
using std::string;

int main()
{
 string s1,s2;

 s1="Hello, ", s2="World!";
 s1=s1+s2;
 printf("s1=%s\n",s1.c_str());
 getchar();

 return 0;
}

...and that produced a 100K program with Dev-Cpp and a 48K program with GNU CodeBlocks, the latter of which allows for optimazations in terms of size. Note I didn't use iostream in that. So that's movement in the right direction anyway.

Frederick2 189 Posting Whiz

Been meaning to ask that question for a long time. With Visual Studio 6 I seem to recall I had to include iostream.h to use the CString class. Do I have that right? I think I also had to specify in a configuration dialog that I wanted to either link statically or dynamically with MFC.dll. Do I have that right?

About five weeks ago I got myself Visual Studio Pro 2008 and I've been just setting up my projects as empty C++ Win32 console or Gui projects as the case may be without MFC support. Naturally, I don't have access to the CString class that way.

My questions are as follows:

1) What is the relationship between iostream.h and MFC? Can the one be used without the other?

2) Is it possible to use the CString class without MFC? Last I recall, the MFC library was upwards of a MB or bigger. I'm not an MFC user at all, but if I could access the CString Class without it, I'd consider it.

3) I just set up a VC9 C++ project (console) where I specified I didn't want to use MFC. However, on the later screen where you would check "Empty File" I checked "Add MFC Support". What I ended up with was a lot of wizzard generated code where both iostream.h and stdio.h were included, and when I declared a CString variable I didn't get an error on compile. However, the resulting Release Build …

Frederick2 189 Posting Whiz

It sounds to me Krisny that you've got to parse the file name apart returned from your directory obtaining function and insert the "\\" characters the compiler wants to see in the string you feed into ShellExecute(). Afterall, you said it works if you feed in a correctly specified path, i/e., "C:\\Dir1\\Dir2\\SomeProgram.exe". You are using MFC and have got a usable String class, No?

Frederick2 189 Posting Whiz

Frederick: In the destructor it is not necessary to check for a NULL pointer -- the delete[] operator works correctly when given a null pointer.

In the constructor: suggest you add the const keyword to the parameter, e.g. String::String(const char* pStr) LenStr: Suggest this be an inline function so that the compiler can optimize it better.

lpStr: ditto as above

Thanks AncientDragon. I'll make especial note of that. I wasn't aware about the delete [] not having a problem with null pointers.

Fred

Frederick2 189 Posting Whiz

I'm glad you guys are enjoying the topic as much as I am! Here is the actual code I'm working with if you want to play with it. Its just enough of my string class to test out my LTrim() member. In my real class I have all the 'Basic Like' String handling functions such as Mid(), Right(), Left(), InStr(), etc., etc.

I've commented out several usable versions of the LTrim() member that could be easily played around with...

//Main.cpp
#include  <stdlib.h>
#include  <stdio.h>
#include  <string.h>

class String
{
 public:
 String();                       //Uninitialized Constructor - Does nothing
 ~String();                      //Destructor
 String& operator=(const char*); //For assigning a literal or null terminated character string to object
 String(char* pStr);             //Constructor with initialization asciiz character array
 unsigned int LenStr();          //String Length
 char* lpStr();                  //Pointer To Beginning Of Null Terminated String
 String& LTrim();                //Trims leading spaces or tabs from beginning of String

 private:
 char*         pStrBuffer;
};


String::String()                 //Uninitialized Constructor - Does nothing
{
 pStrBuffer=NULL;
}


String::String(char* pStr)       //Constructor with initialization asciiz character array
{
 pStrBuffer=new char[strlen(pStr)+1];
 strcpy(pStrBuffer,pStr);
}


String& String::operator=(const char* pStr)
{
 if(this->pStrBuffer)
    delete [] pStrBuffer;
 pStrBuffer=new char[strlen(pStr)+1];
 strcpy(pStrBuffer,pStr);

 return *this;
}


String::~String()             //Destructor
{
 if(pStrBuffer)               //Don't try to [] delete a NULL pointer!
    delete [] pStrBuffer;
}


unsigned int String::LenStr(void)
{
 puts("  Called String::LenStr()");
 return strlen(this->pStrBuffer);
}


char* String::lpStr()
{
 return pStrBuffer;
}


String& String::LTrim()
{
 unsigned int i,iCt=0,iLenStr=0;
 
 printf("\nEntering String::LTrim()\n");
 iLenStr=this->LenStr();
 for(i=0;i<iLenStr;i++)
 {
     if(pStrBuffer[i]==32||pStrBuffer[i]==9)
        iCt++;
     else
        break;
 }
 printf("  iCt = %u\n",iCt);
 iLenStr=this->LenStr();
 for(i=iCt;i<=iLenStr;i++)
 {
     pStrBuffer[i-iCt]=pStrBuffer[i];
     printf("  %u\t%c\t%c\n",i,pStrBuffer[i-iCt],pStrBuffer[i]);
 }
 printf("  pStfBuffer = …
Frederick2 189 Posting Whiz

No, I take that back. Just ran a test. Either way it only iterates twice. Here is the output without the function call in the for loop...

s1.lpStr()  =      F
  Called String::LenStr()
s1.LenStr() = 6

Entering String::LTrim()
  Called String::LenStr()
  iCt = 5
  Called String::LenStr()
  5     F       F
  6
  pStfBuffer = F
  F     70
  &pStrBuffer[0] = 4260080
Leaving String::LTrim()

s1.lpStr()  = F
  Called String::LenStr()
s1.LenStr() = 1
Frederick2 189 Posting Whiz

The way I discovered it was that my code was working too good! I'm not happy when things work too good. I prefer things to work badly at first. Then I gradually find out what's wrong and fix it. I'm more comfortable with that. When things work too good I know I'm in for trouble somewhere!

Anyway, what I was doing was working on my 'own' asciiz string class. I wanted a member function to trim whitespace from the front of a String. What I decided to do was start at the beginning of the asciiz buffer at offset 0 and count white space chars up to the first printable char. Then run a for loop starting at the first printable char and offsetting the characters back to the beginning. So if I have the 1st letter of my name with 5 spaces in front of it like so...

s1="     F"

...I'd have a String with a length of 6 and there would be a NULL after the 6th char, i.e., the 'F'. In the String class the only member variable is a char* pStrBuffer. There is a member function to return its length...

int String::LenStr()
{
 return strlen(this->pStrBuffer);
}

And my LTrim() looked like this...

String& String::LTrim()
{
 unsigned int i,iCt=0;

 for(i=0;i<this->LenStr();i++)                //Start at beginning of String
 {                                            //and count # of white space
     if(pStrBuffer[i]==32||pStrBuffer[i]==9)  //chars up to 1st printable
        iCt++;                                //char.
     else
        break;
 }
 for(i=iCt;i<=this->LenStr();i++)             //bump printable chars up iCt
     pStrBuffer[i-iCt]=pStrBuffer[i];         //bytes.
 
 return *this; …
Frederick2 189 Posting Whiz

Not stuck and no real question, which is unusual for me. Just a comment. The 2nd term in a for loop establishes the condition under which the loop terminates. For example, this loop terminates when i increments to 5...

for(i=0; i<=5; i++)
{
...
...
}

It'll execute its contents 6 times.

The terminating condition, i.e., i=5, seems to be determined one time. However, if a function call is placed in the terminating condition, such as...

for(i=0; i<=this->LenStr(); i++)
{
...
...
}

...then that function call (a class member function, in the above case), is evaluated every iteration of the loop! I simply didn't know that and it amazed me. Any comments???

Frederick2 189 Posting Whiz

That thread's pretty longish. If you want to cut right to the heart go to reply 16.