Thread: Getting FunctionX Tutorial to Work

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    127

    Getting FunctionX Tutorial to Work

    Hi,

    I've been trying to do some of the examples on functionx.com, but I'm having difficulty getting one of them to compile. I'm working from this tutorial:

    Win32 Programming - Lesson 6: Object-Oriented Win32

    I copied out the code for the example program beneath the heading "Win32 Object Programming", which is about halfway down that page. As instructed, I created "MainWnd.h", "WinApp.h", "WinApp.cpp", and "Exercise.cpp".

    Initially, I had a few problems with converting between different types of char variable. SO in exercise.cpp, I changed WinMain to look like this:

    Code:
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,
                                        LPSTR lpCmdLine, int nCmdShow)
    {
        MSG Msg;
        LPCTSTR ClsName_T = L"Win32OOP";
        LPCTSTR WndName = L"Object-Oriented Win32 Programming";
    
        int copy1 = 0;
        char *ClsName_CH = "";
        copy1 = WideCharToMultiByte(CP_ACP, WC_SEPCHARS, ClsName_T, -1, ClsName_CH, -1, NULL, NULL);
    
        // Initialize the application class
        WApplication WinApp(hInstance, ClsName_CH, MainWndProc);
        WinApp.Register();
    
        // Create the main window
        WWindow Wnd;
        Wnd.Create(hInstance, ClsName_T, WndName);
        // Display the main window
        Wnd.Show();
    
        // Process the main window's messages
        while ( GetMessage(&Msg, NULL, 0, 0) )
        {
                TranslateMessage(&Msg);
                DispatchMessage(&Msg);
        }
    
        return 0;
    }
    Similarly, in WinApp.cpp, I changed WApplication::WApplication to look like this:

    Code:
    WApplication::WApplication(HINSTANCE hInst, char *ClsName,
                               WNDPROC WndPrc, LPCTSTR MenuName)
    {
        int copy1 = 0;
        LPCSTR ClsName_C = ClsName;
        LPWSTR ClsName_W;
        copy1 = MultiByteToWideChar(CP_ACP, WC_SEPCHARS, ClsName_C, -1, ClsName_W, 0);
        // Should add error handling code here in case the above returns zero.
    
        // Initializing the application using the application member variable
        _WndClsEx.cbSize        = sizeof(WNDCLASSEX);
        _WndClsEx.style         = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
        _WndClsEx.lpfnWndProc    = WndPrc;
        _WndClsEx.cbClsExtra    = 0;
        _WndClsEx.cbWndExtra    = 0;
        _WndClsEx.hInstance     = hInst;
        _WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        _WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
        _WndClsEx.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
        _WndClsEx.lpszMenuName  = MenuName;
        _WndClsEx.lpszClassName = ClsName_W;
        _WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    }
    That got rid of the compiler errors relating to the conversions between the char variables, but another problem arose. When I tried to compile, I got "3 unresolved externals". They are:

    Exercise.obj : error LNK2019: unresolved external symbol "public: int __thiscall WWindow::Show(int)" (?Show@WWindow@@QAEHH@Z) referenced in function _WinMain@16

    Exercise.obj : error LNK2019: unresolved external symbol "public: struct HWND__ * __thiscall WWindow::Create(struct HINSTANCE__ *,wchar_t const *,wchar_t const *,struct HWND__ *,unsigned long,unsigned long,int,int,int,int)" (?Create@WWindow@@QAEPAUHWND__@@PAUHINSTANCE__@@PB _W1PAU2@KKHHHH@Z) referenced in function _WinMain@16

    Exercise.obj : error LNK2019: unresolved external symbol "public: __thiscall WWindow::WWindow(void)" (??0WWindow@@QAE@XZ) referenced in function _WinMain@16

    Does anyone know how I can fix this problem? After looking around for a solution, I think I may need to include some libraries or something but I'm not sure how exactly.

    Thanks.
    Last edited by bengreenwood; 08-05-2009 at 09:54 AM.

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    It sounds like you are not building MainWnd.cpp (The file with the WWindow classes source files).
    bit∙hub [bit-huhb] n. A source and destination for information.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    127
    Quote Originally Posted by bithub View Post
    It sounds like you are not building MainWnd.cpp (The file with the WWindow classes source files).
    You're right. I managed to miss that entire source file entirely. Oops.

    But now that I've done it, I've got another problem. Now it compiles and runs, but a debug error box comes up warning me that "The variable ClsName_W is being used without being initialized." Obviously, this is to do with some of the code I changed due to the char conversion errors:

    (in WinApp.cpp)

    Code:
        int copy1 = 0;
        LPCSTR ClsName_C = ClsName;
        LPWSTR ClsName_W;
        copy1 = MultiByteToWideChar(CP_ACP, WC_SEPCHARS, ClsName_C, -1, ClsName_W, 0);
    Anyone know how I get around this problem?

    Thanks.

    EDIT: I was advised recently not to declare variables uninitialized. I'm not ignoring what I was told, but I'm not sure how I could initialize ClsName_W as it's declared.

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    You are calling functions without understanding what it is they are doing. Look at the documentation for MultiByteToWideChar. The last two parameters are a buffer to place the result into, and the size of that buffer. You are passing a pointer (not a buffer which actual space to fill out), and then you say the size of that buffer is zero. What do you expect this function to do?

    If you instead declared the buffer like this, I think you would have more luck.
    Code:
    WCHAR buffer[100];
    bit∙hub [bit-huhb] n. A source and destination for information.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    127
    Quote Originally Posted by bithub View Post
    You are calling functions without understanding what it is they are doing. Look at the documentation for MultiByteToWideChar. The last two parameters are a buffer to place the result into, and the size of that buffer. You are passing a pointer (not a buffer which actual space to fill out), and then you say the size of that buffer is zero. What do you expect this function to do?

    If you instead declared the buffer like this, I think you would have more luck.
    Code:
    WCHAR buffer[100];
    Ah, ok, thanks. Pretty stupid mistake that one. Maybe this thread isn't my finest hour.

    Actually I just found another solution. I altered the parameter list of WApplication so that instead of "char *ClsName" it includes "LPWSTR ClsName_W".

    Then I altered a line in WinApp.cpp:

    Code:
    _WndClsEx.lpszClassName = ClsName_W;
    And in Exercise.cpp I added:

    Code:
    LPWSTR ClsName_W = L"Win32OOP";
    and altered an existing line in Exercise.cpp to:

    Code:
    WApplication WinApp(hInstance, ClsName_W, MainWndProc);
    This approach also seemed to work ok. Which method do you think is better?

    Thanks for your help. It's good to be making progess with this.

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Any approach which limits the conversion from wide-char to char and vice-versa is better. You should only work with one charset if you can help it, and keep the conversions to a minimum.
    bit∙hub [bit-huhb] n. A source and destination for information.

  7. #7
    Registered User
    Join Date
    Sep 2007
    Posts
    127
    Say I write the following:

    Code:
    char *ClsName = "Win32OOP";
    And I also want to do this:

    Code:
    LPCWSTR ClsName_W = L"Win32OOP";
    Is there any way I can use L with ClsName so that I don't have to write out "Win32OOP" twice? I tried L(ClsName) but my compiler gave me this: error C3861: 'L': identifier not found

    Thanks.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    You can do a little trickery with the preprocessor:

    Code:
    // Declare these in some global header file
    #define _WIDE(x) L ## x
    #define WIDE(x) WIDE(x)
    
    // ... then in your code:
    #define CLASS_NAME "Win32OOP"
    
    const char *ClsName = CLASS_NAME;
    LPCWSTR ClsName_W = WIDE(CLASS_NAME);
    bit∙hub [bit-huhb] n. A source and destination for information.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. LibBZip2 tutorial search trouble
    By Chris87 in forum C Programming
    Replies: 3
    Last Post: 04-29-2010, 06:55 AM
  2. random number tutorial
    By 7stud in forum C++ Programming
    Replies: 3
    Last Post: 07-26-2005, 02:41 PM
  3. capture card wont work with xp
    By scott27349 in forum Tech Board
    Replies: 6
    Last Post: 02-08-2005, 09:47 PM
  4. If you are employed as a programmer, please look
    By Flood Fighter in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 09-28-2004, 02:35 AM