Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

[C++] Can't figure it out

  1. Jan 28, 2014 #1
    What is wrong with the code? I can't figure it out, it works in dev c++ but windows visual studios doesn't work :(

    Code (Text):
    #include <windows.h>
    #include <iostream>
    #include <sstream>
    #include <string>

    using namespace std;

    /*Declares Window Procedure*/
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM,LPARAM);
    HWND Textfield,Button;

    char szClassName [] =  "Windows App";

    int WINAPI WinMain(HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
    {
        HWND hwnd; /*This is the handle for our window*/
        MSG messages; /*Here messages to the application are saved*/
        WNDCLASSEX wincl; /*Data structures for windowclass*/

        /*Window Structure*/
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = *szClassName;
        wincl.lpfnWndProc = WindowProcedure; /*This Function is called by Windowss*/
        wincl.style = CS_DBLCLKS; /*Catches Double Clicks*/
        wincl.cbSize = sizeof(WNDCLASSEX);
       
        /*Use default icon and mouse-pointer*/
        wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL; /*No Menu Name*/
        wincl.cbClsExtra = 0; /*No Extrea bytes after he window class*/
        wincl.cbWndExtra = 0;/*Structure or the window instance*/
       
        /*Use of Window's Default colour as the background of the window*/
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
       
        /*Register the window class,and if it fails quit the program*/
        if(!RegisterClassEx(&wincl))
        {return 0;}
       
        hwnd = CreateWindowEx
        (
            0,      /*Extended possibilities fo variation*/
            szClassName, /*Classname*/
            "App",      /*Title txt*/
            WS_OVERLAPPEDWINDOW, /*default Window can resize*/
            CW_USEDEFAULT, /*Windows Decides the position*/
            CW_USEDEFAULT,/*Where the window ends up in the screen*/
            544, /*the programs Width*/
            375, /*Programs hight in pixels*/
            HWND_DESKTOP,/*the window is a child-window to desktop*/
            NULL, /*No menu*/
            hThisInstance,/*Program Instancehandler*/
            NULL/*No Window Creation data*/
        );
       
        /*Make the window visible on screen*/
        ShowWindow (hwnd, nCmdShow);
       
        /*Run the message loop. It wil run until GetMessage() returns 0*/
        while (GetMessage(&messages,NULL,0,0))
        {
            /*Translates virtural-Key messages into character messages*/
            TranslateMessage(&messages);
           
            /*Sends message to WindowProcedure*/
            DispatchMessage(&messages);
        }
        /*Returns value of 0, the Value that PostQuitMessage() gave*/
        return messages.wParam;
       
    }


    /*This function is called by the Windows Function DispatchMessage()*/
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
    {
        switch (message)  /*handle the messages*/
        {
            case WM_CREATE:
                Textfield = CreateWindow("EDIT","Hello World",WS_VISIBLE| WS_CHILD|WS_BORDER,20 , 20, 300,25,hwnd, NULL, NULL, NULL);
                Button = CreateWindow ("Button","Yes", WS_VISIBLE|WS_CHILD |WS_BORDER, 120,120,100,20 , hwnd, (HMENU) 1,NULL, NULL);
                Button = CreateWindow ("Button","No", WS_VISIBLE|WS_CHILD |WS_BORDER, 280,120,100,20 , hwnd, (HMENU) 2,NULL, NULL);    
               
                break;
            case WM_DESTROY:
                PostQuitMessage(0); /*Send a WM_QUIT to the message queue*/
                break;
            case WM_COMMAND:
                switch(LOWORD(wParam))
                {
                    case 1:
                        cout << " Awesome Job! \0 \n \a";
                    break;
                    case 2:
                        ::MessageBox(hwnd, "You Are Now Dead","You Pushed My Buttons",MB_OK);
                        ::MessageBeep(MB_ICONERROR);
                        PostQuitMessage(0);
                    break;
                }
                break;     
            default:            /*for messages that we don't deal with*/
                return DefWindowProc(hwnd, message, wParam, lParam);
        }
        return 0;
    }
    here are the erros:
    1>Windowed Application.cpp
    1>c:\users\noodle\documents\visual studio 2008\projects\windowed application\windowed application\windowed application.cpp(22) : error C2440: '=' : cannot convert from 'char' to 'LPCWSTR'
    1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
    1>c:\users\noodle\documents\visual studio 2008\projects\windowed application\windowed application\windowed application.cpp(56) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'char [12]' to 'LPCWSTR'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\users\noodle\documents\visual studio 2008\projects\windowed application\windowed application\windowed application.cpp(82) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [5]' to 'LPCWSTR'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\users\noodle\documents\visual studio 2008\projects\windowed application\windowed application\windowed application.cpp(83) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [7]' to 'LPCWSTR'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\users\noodle\documents\visual studio 2008\projects\windowed application\windowed application\windowed application.cpp(84) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [7]' to 'LPCWSTR'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\users\noodle\documents\visual studio 2008\projects\windowed application\windowed application\windowed application.cpp(97) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [17]' to 'LPCWSTR'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>Build log was saved at "file://c:\Users\Noodle\Documents\Visual Studio 2008\Projects\Windowed Application\Windowed Application\Debug\BuildLog.htm"
    1>Windowed Application - 6 error(s), 0 warning(s)
     
  2. jcsd
  3. Jan 29, 2014 #2

    SixNein

    User Avatar
    Gold Member

    The variable you defined is a char array; however, the member of the structure your trying to assign to the variable is a different type. So the types don't match and the compiler is complaining.

    Here is a reference to the types in windows:
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx

    So you can use the CString class to manage your strings in windows which works very similar to the STL string library. Or you can go use a LPCTSTR; however, a char array wont work. From your compiler output, it seems that you are using Unicode. So the LPCTSTR will be defined as LPCWSTR which is a const WCHAR*.
     
  4. Jan 29, 2014 #3

    rcgldr

    User Avatar
    Homework Helper

    Right click on project, select properties, select all configurations, and change character set from "use unicode ... " to "not set".
     
  5. Jan 29, 2014 #4
    rcgldr’s suggestion will work (plus removing the unnecessary * on line 22), but you can also convert your code to work with Unicode. I would argue that changing the code is a better solution, as it makes your program more flexible, but also requires keeping in mind the difference between 1-byte characters and wide characters as you continue to develop your app.

    To fix the code, include tchar.h. Then change line 12 to TCHAR szClassName [] = _T("Windows App"); Also add _T() around any strings in the other lines with errors, e.g. around "App" in the call to CreateWindowEx() and "Edit" in CreateWindow().

    You’ll also need to keep in mind other differences between using TCHARS and basic chars as you continue to develop your program. For more information, search for TCHAR online.

    (If you would prefer to remove one level of indirection and instead hard-code your app to use Unicode, you can use wchar_t instead of TCHAR and prepend your strings with L instead of wrapping them with _T().)
     
    Last edited: Jan 29, 2014
  6. Jan 29, 2014 #5
    The very first error is caused by wincl.lpszClassName = *szClassName;

    * in front of szClassName extracts the very first char from the array, and the char is definitely not a pointer to a string that wincl.lpszClassName is.

    I would recommend against doing that. All modern version of Windows use "Unicode" (technically, UTF-16) everywhere they deal with strings. If your code uses "ASCII", it really uses some (usually) unknown multibyte encoding and Windows converts back and forth. It tries hard, and that usually works - as long as your users are primarily English speakers. Then somebody feeds your code characters from a different alphabet, and weird things happen.
     
  7. Jan 29, 2014 #6
    Okay, thank you all but not I have another problem, it gives me a linker error

    1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
    1>C:\Users\Noodle\Documents\Visual Studio 2008\Projects\Windowed Application\Debug\Windowed Application.exe : fatal error LNK1120: 1 unresolved externals

    :/ I don't understand I don't have this problem with Dev C++... D:
     
  8. Jan 29, 2014 #7
    Your are building your program as a console application (which must have a main function). While your code is written for a GUI application (which must have a WinMain function). You can change that in the project settings, the subsystem linker option. Or you can just create another project and make sure that you select the proper application type (GUI).
     
  9. Jan 30, 2014 #8
    Okay, what do you mean. I am using c++ visual studio 08 and I can't figure out where I go to change the project settings, the subsystem linker options so that it accepts my... I don't know how to create a GUI app in VS 08 >///<

    P.S.
    I have been having a lot of problems with linking :/ same with DevC++
     
  10. Jan 30, 2014 #9
    I do not have VS 2008 at hand and cannot recall what exactly needs to be done there. Perhaps someone else can.

    It does seem to me, however, that you are trying things without really understanding what you are doing.

    Besides, these days, I would not recommend learning to program for Windows in C or C++ using the low-level Windows API. That's just too hard and may even be becoming insignificant as an occupation.
     
  11. Jan 30, 2014 #10

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    I just googled "visual studio 2008 change project settings" and got the answer quicker than firing up VS2008 :smile:
    http://msdn.microsoft.com/en-us/library/z15yzzew.aspx

    But voko's earlier advice
    is the easiest way. Let the nice people at Microsoft generate everything you need for an application that compiles and runs but doesn't do anything. Then add your own code to it.
     
  12. Jan 30, 2014 #11

    SixNein

    User Avatar
    Gold Member

    On a side note, I really recommend using the CString class instead of managing the pointers themselves. http://msdn.microsoft.com/en-us/library/ms174288.aspx
     
  13. Jan 31, 2014 #12
    Assuming your app is coded as a console application, I suggest you create a new console app in VS2008 and copy the existing source into that project.

    Here is how to do that:
    From VS2008, select File->New->Project...
    From the "New Project" window, select "Visual C++->Win32"
    In the "Templates" pane, select "Win32 Console Application"
    Specify you project name, folder location, and solution name.
    Leave "Create directory for solution" checked.
    Click "OK"
    In the "Win32 Application Wizard"m click "Finish".

    Assuming you want to stick to the ASCII character set.
    In the "Microsoft Visual Studio" window, press Alt-F7
    In the "Property Page" window, select Configuration Properties->General
    Set "Configuration" (above panes) to the "All Configurations" selection.
    In the right pane, set "Character Set" to "Not Set".
    Click "OK"
    Select File->Save All.

    Copy you source into the project directory and add them to the project.
     
  14. Jan 31, 2014 #13
    The code in #1 is very clearly not of a console application. I suggest you instead explain how to create a GUI application project in VS 2008, which you seem to have access to. Or perhaps remember by heart? :)
     
  15. Jan 31, 2014 #14
    Oh yeah. He's using MFC.
    So somehow he got Win32 code into a console project?

    Okay then...

    From VS2008, select File->New->Project...
    From the "New Project" window, select "Visual C++->Win32"
    In the "Templates" pane, select "Win32 Project"
    Specify you project name, folder location, and solution name.
    Leave "Create directory for solution" checked.
    Click "OK"
    In the "Win32 Application Wizard", click "Finish".

    Assuming you want to stick to the ASCII character set.
    In the "Microsoft Visual Studio" window, press Alt-F7
    In the "Property Page" window, select Configuration Properties->General
    Set "Configuration" (above panes) to the "All Configurations" selection.
    In the right pane, set "Character Set" to "Not Set".
    Click "OK"
    Select File->Save All.

    Copy your source into the project directory and add them to the project.

    I don't remember anything by heart. I have several development environments on my workstation - including VS 2008.
     
    Last edited: Jan 31, 2014
  16. Jan 31, 2014 #15
    Actually, he is not. But there is a WinMain routine with boilerplate create window - run message loop code in it.

    Yes, judging from the linker's output.

    I expected no less, but could not resist making a joke. Sorry if its silliness was a bit too silly, I did not mean it to be offensive.
     
  17. Jan 31, 2014 #16
    I thought as much - and it was not too silly. I'm not one to take offense at anything short of violence. As best I can tell, it was in no way offensive.
     
  18. Jan 31, 2014 #17

    rcgldr

    User Avatar
    Homework Helper

    Doesn't look like MFC to me. It looks like "classic" windows C code, with a GetMessage ... DispatchMessage loop.

    Note, when creating the project, instead of clicking on "finish", click on next, and uncheck all the boxes like "pre-compiled headers", and then click on "empty project" to check that box. Otherwise VS will add some extra junk you probably don't want in your project.

    For this application's windows resources, are you using a text file or are you using the resource editor?
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook