1

I have coded some C++ console program which converts one filetype to another. I need to turn the console application into a window one. I have never made window applications. I have chosen WinApi, because I don't have much time and don't want to change IDE (DEV C++ 5.10), compiler/linker settings etc. I need a small simple window. Parameters I need to get from the user are: path for input file, name and path for output file, and two parameters of type double. I have started to experiment, and wanted to put the text from window to a .txt file. The problem is what I get in the .txt file. My code:

#include <windows.h>
#include <string>
#include <fstream>
#include <iostream>

using namespace std;

HWND g_hText;

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    switch(Message) {

        case WM_CLOSE:
        {
            DestroyWindow( hwnd );
        }
        break;

        case WM_DESTROY: {
            PostQuitMessage(0);
            break;
        }

        //here I create the file and write to it
        case WM_COMMAND:
        {   if(( HWND ) lParam == g_hText )
            {   DWORD dlugosc = GetWindowTextLength( g_hText );
                LPSTR Bufor =( LPSTR ) GlobalAlloc( GPTR, dlugosc + 1 );
                GetWindowText( g_hText, Bufor, dlugosc + 1 );

                ofstream out("some_file.txt",ios_base::app);
                out<<Bufor;
                out.close();
            }
            break;  
        }

        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);

        }

    return 0;
    }

    MSG msg;

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX wc;
    HWND hwnd;

    memset(&wc,0,sizeof(wc));//sprawdzic co to
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra = 0;
    wc.hInstance     = hInstance;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "WindowClass";
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
        return 0;
    }

    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        640,
        480,
        NULL,NULL,hInstance,NULL);

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

    g_hText = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
    200, 0, 150, 30, hwnd, NULL, hInstance, NULL );

    while(GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

When I type, for example, "qwerty" in the text window, I get "qqqwqwqweqweqwerqwerqwertqwertqwertyqwertyqwerty" in the text file. The text from the window is being read continually. I was trying to make it being read after pressing "Enter"

case WM_COMMAND:
{   if(( HWND ) lParam == g_hText )
    {    if(WM_KEYDOWN)
        {    if(VK_RETURN)
            {   DWORD dlugosc = GetWindowTextLength( g_hText );
                LPSTR Bufor =( LPSTR ) GlobalAlloc( GPTR, dlugosc + 1 );
                GetWindowText( g_hText, Bufor, dlugosc + 1 );

                ofstream out("some_file.txt",ios_base::app);
                out<<Bufor;
                out.close();
            }
            break;  
        }

        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);

        }
    }
}

but with no effect. How should it be done to be done properly?

2
  • I am confused about your mention of WM_KEYDOWN and VK_RETURN, since they show up nowhere in the code you posted. Are you actually using it somewhere in your code? Commented Jun 12, 2015 at 12:54
  • I have used it, but deleted it since it didn't work. I have edited the post. Commented Jun 12, 2015 at 13:07

1 Answer 1

2

You need to properly handle WM_KEYDOWN, not WM_COMMAND, because windows receives WM_KEYDOWN after key is pressed and WM_COMMAND after variuos of events.

case WM_KEYDOWN:
{   
    if(wParam == VK_RETURN)
    {   
        DWORD dlugosc = GetWindowTextLength( g_hText );
        LPSTR Bufor =( LPSTR ) GlobalAlloc( GPTR, dlugosc + 1 );
        GetWindowText( g_hText, Bufor, dlugosc + 1 );

        ofstream out("some_file.txt",ios_base::app);
        out<<Bufor;
        out.close();
    }
    break;  
}

Also,

if(WM_KEYDOWN)
if(VK_RETURN)

These two lines basically are if (true) and don't forget to free allocated memory.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you; I misunderstood the basics, obviously.
Do note that if the user holds the Return key down, you will get multiple WM_KEYDOWN messages with an incrementing repeat counter. So either handle WM_KEYUP instead, or change the app design. For a GUI app, it makes more sense to have the user press a button when ready to process entered input, don't process on individual keystrokes. You can detect that button press by handling the BN_CLICKED notification.
@RemyLebeau. Thank you for the tip. Pressing a button when ready sounds better for me, it seems to give clearer code. I'll try this design.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.