error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup MSVCRTD.lib Win32App

  • Follow


Hi,
I am trying a very simple windows tutorial, all code is from the
tutorial but at compile time it is giving the above error. I am using
Visual Studio 2008 C++, starting with an empty project, Here is the
code:
Any ideas, where is this function _tmainCETStartup coming in from and
where should be what it is looking for?

#include <windows.h>

LPCTSTR ClsName = L"BasicApp";
LPCTSTR WndName = L"A Simple Window";

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
			      WPARAM wParam, LPARAM lParam);

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
               LPSTR lpCmdLine, int nCmdShow)
{
	MSG        Msg;
	HWND       hWnd;
	WNDCLASSEX WndClsEx;

	// Create the application window
	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
	WndClsEx.lpfnWndProc   = WndProcedure;
	WndClsEx.cbClsExtra    = 0;
	WndClsEx.cbWndExtra    = 0;
	WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClsEx.lpszMenuName  = NULL;
	WndClsEx.lpszClassName = ClsName;
	WndClsEx.hInstance     = hInstance;
	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

	// Register the application
	RegisterClassEx(&WndClsEx);

	// Create the window object
	hWnd = CreateWindow(ClsName,
			  WndName,
			  WS_OVERLAPPEDWINDOW,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  NULL,
			  NULL,
			  hInstance,
			  NULL);

	// Find out if the window was created
	if( !hWnd ) // If the window was not created,
		return 0; // stop the application

	// Display the window to the user
	ShowWindow(hWnd, SW_SHOWNORMAL);
	UpdateWindow(hWnd);

	// Decode and treat the messages
	// as long as the application is running
	while( GetMessage(&Msg, NULL, 0, 0) )
	{
             TranslateMessage(&Msg);
             DispatchMessage(&Msg);
	}

	return Msg.wParam;
}

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
			   WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
    // If the user wants to close the application
    case WM_DESTROY:
        // then close it
        PostQuitMessage(WM_QUIT);
        break;
    default:
        // Process the left-over messages
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    // If something was not done, let it go
    return 0;
}
0
Reply Tauqir 4/5/2010 12:22:40 AM


"Tauqir" <tauqirghani@yahoo.com> wrote in message 
news:5c34cb6c-51dc-436a-b258-117fadfd9441@30g2000yqi.googlegroups.com...
> Hi,
> I am trying a very simple windows tutorial, all code is from the
> tutorial but at compile time it is giving the above error. I am using
> Visual Studio 2008 C++, starting with an empty project, Here is the
> code:
> Any ideas, where is this function _tmainCETStartup coming in from and
> where should be what it is looking for?
>
> #include <windows.h>
>
> LPCTSTR ClsName = L"BasicApp";
> LPCTSTR WndName = L"A Simple Window";
>
> LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
>       WPARAM wParam, LPARAM lParam);
>
> INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
>               LPSTR lpCmdLine, int nCmdShow)
> {
> MSG        Msg;
> HWND       hWnd;
> WNDCLASSEX WndClsEx;
>
> // Create the application window
> WndClsEx.cbSize        = sizeof(WNDCLASSEX);
> WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
> WndClsEx.lpfnWndProc   = WndProcedure;
> WndClsEx.cbClsExtra    = 0;
> WndClsEx.cbWndExtra    = 0;
> WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
> WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
> WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
> WndClsEx.lpszMenuName  = NULL;
> WndClsEx.lpszClassName = ClsName;
> WndClsEx.hInstance     = hInstance;
> WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
>
> // Register the application
> RegisterClassEx(&WndClsEx);
>
> // Create the window object
> hWnd = CreateWindow(ClsName,
>   WndName,
>   WS_OVERLAPPEDWINDOW,
>   CW_USEDEFAULT,
>   CW_USEDEFAULT,
>   CW_USEDEFAULT,
>   CW_USEDEFAULT,
>   NULL,
>   NULL,
>   hInstance,
>   NULL);
>
> // Find out if the window was created
> if( !hWnd ) // If the window was not created,
> return 0; // stop the application
>
> // Display the window to the user
> ShowWindow(hWnd, SW_SHOWNORMAL);
> UpdateWindow(hWnd);
>
> // Decode and treat the messages
> // as long as the application is running
> while( GetMessage(&Msg, NULL, 0, 0) )
> {
>             TranslateMessage(&Msg);
>             DispatchMessage(&Msg);
> }
>
> return Msg.wParam;
> }
>
> LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
>    WPARAM wParam, LPARAM lParam)
> {
>    switch(Msg)
>    {
>    // If the user wants to close the application
>    case WM_DESTROY:
>        // then close it
>        PostQuitMessage(WM_QUIT);
>        break;
>    default:
>        // Process the left-over messages
>        return DefWindowProc(hWnd, Msg, wParam, lParam);
>    }
>    // If something was not done, let it go
>    return 0;
> }

Try creating the project again but this time choose "Win32 Project / Windows 
Application" and not "Win32 Console Application / Console Application".

Cheers,
Leigh. 

0
Reply Leigh 4/5/2010 12:47:36 AM



"Leigh Johnston" <leigh@i42.co.uk> wrote in message 
news:CvmdndQsxObdriTWnZ2dnUVZ8hqdnZ2d@giganews.com...
>
>
> "Tauqir" <tauqirghani@yahoo.com> wrote in message 
> news:5c34cb6c-51dc-436a-b258-117fadfd9441@30g2000yqi.googlegroups.com...
>> Hi,
>> I am trying a very simple windows tutorial, all code is from the
>> tutorial but at compile time it is giving the above error. I am using
>> Visual Studio 2008 C++, starting with an empty project, Here is the
>> code:
>> Any ideas, where is this function _tmainCETStartup coming in from and
>> where should be what it is looking for?
>>
>> #include <windows.h>
>>
>> LPCTSTR ClsName = L"BasicApp";
>> LPCTSTR WndName = L"A Simple Window";
>>
>> LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
>>       WPARAM wParam, LPARAM lParam);
>>
>> INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
>>               LPSTR lpCmdLine, int nCmdShow)
>> {
>> MSG        Msg;
>> HWND       hWnd;
>> WNDCLASSEX WndClsEx;
>>
>> // Create the application window
>> WndClsEx.cbSize        = sizeof(WNDCLASSEX);
>> WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
>> WndClsEx.lpfnWndProc   = WndProcedure;
>> WndClsEx.cbClsExtra    = 0;
>> WndClsEx.cbWndExtra    = 0;
>> WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
>> WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
>> WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
>> WndClsEx.lpszMenuName  = NULL;
>> WndClsEx.lpszClassName = ClsName;
>> WndClsEx.hInstance     = hInstance;
>> WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
>>
>> // Register the application
>> RegisterClassEx(&WndClsEx);
>>
>> // Create the window object
>> hWnd = CreateWindow(ClsName,
>>   WndName,
>>   WS_OVERLAPPEDWINDOW,
>>   CW_USEDEFAULT,
>>   CW_USEDEFAULT,
>>   CW_USEDEFAULT,
>>   CW_USEDEFAULT,
>>   NULL,
>>   NULL,
>>   hInstance,
>>   NULL);
>>
>> // Find out if the window was created
>> if( !hWnd ) // If the window was not created,
>> return 0; // stop the application
>>
>> // Display the window to the user
>> ShowWindow(hWnd, SW_SHOWNORMAL);
>> UpdateWindow(hWnd);
>>
>> // Decode and treat the messages
>> // as long as the application is running
>> while( GetMessage(&Msg, NULL, 0, 0) )
>> {
>>             TranslateMessage(&Msg);
>>             DispatchMessage(&Msg);
>> }
>>
>> return Msg.wParam;
>> }
>>
>> LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
>>    WPARAM wParam, LPARAM lParam)
>> {
>>    switch(Msg)
>>    {
>>    // If the user wants to close the application
>>    case WM_DESTROY:
>>        // then close it
>>        PostQuitMessage(WM_QUIT);
>>        break;
>>    default:
>>        // Process the left-over messages
>>        return DefWindowProc(hWnd, Msg, wParam, lParam);
>>    }
>>    // If something was not done, let it go
>>    return 0;
>> }
>
> Try creating the project again but this time choose "Win32 Project / 
> Windows Application" and not "Win32 Console Application / Console 
> Application".
>

After doing that ensure you use the following for "WinMain":

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
}

Especially important is the LPTSTR to avoid Unicode/ANSI problems although 
the linker might be forgiving.

/Leigh 

0
Reply Leigh 4/5/2010 1:00:36 AM

* Leigh Johnston:
> * Leigh Johnston:
>> * Tauqir:
>>>
>>> I am trying a very simple windows tutorial, all code is from the
>>> tutorial but at compile time it is giving the above error. I am using
>>> Visual Studio 2008 C++, starting with an empty project, Here is the
>>> code:
>>> Any ideas, where is this function _tmainCETStartup coming in from and
>>> where should be what it is looking for?
[snip code]
>>
>> Try creating the project again but this time choose "Win32 Project / 
>> Windows Application" and not "Win32 Console Application / Console 
>> Application".
> 
> After doing that ensure you use the following for "WinMain":
> 
> int APIENTRY _tWinMain(HINSTANCE hInstance,
>                     HINSTANCE hPrevInstance,
>                     LPTSTR    lpCmdLine,
>                     int       nCmdShow)
> {
> }
> 
> Especially important is the LPTSTR to avoid Unicode/ANSI problems 
> although the linker might be forgiving.

Tauqir: evidently you mistyped the name of the missing function. I presume it 
was 'mainCRTStartup'.

'mainCRTStartup' is one of several Microsoft runtime library functions that can 
be used as your program's entry point, where the execution starts. This 
particular function calls a standard C or C++ 'main' function, which you are 
supposed to define. The others call other non-standard startup functions such as 
WinMain.

With Microsoft's toolchain one way to specify which entry point function to use 
is to choose the right project type in Visual Studio, as Leigh advised. 
Ultimately that translates down to an /entry option being passed to the linker, 
or no such option (for the default). The determination of a default is intricate 
and as far as I know not documented, so to take charge, when you want to do 
that, you need to use /entry (it can be specified in the project settings).

Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like "we 
all know that" among many Windows programmers. However, it's advice that once 
(early to middle 90's) was great, but which after that is wrong, perpetuated by 
bad Microsoft code examples and copycat programming & teaching. It's like advice 
talking about proper care of horses in order to help you drive safely to work.

First, the OP's code uses plain Unicode string like L"ouch", which means the 
source will only compile with one setting of T-stuff, namely Unicode.

Secondly, supporting Windows 9x, which the T-stuff is about, is as of 2010 not 
worth the effort.

Third, except when using MFC the way to go for supporting Unicode in Windows 9x 
(if some evil manager requires that) is to use Microsoft's Layer for Unicode.

In short, T-stuff is just silly and adds a lot of needless work, and if one 
absolutely feels that one must use a Microsoft specific startup function instead 
of standard 'main', then that should be 'wMain' or 'wWinMain' (Unicode).

Here's the OP's code reworked to less Microsoft'isms, less C'isms, and without 
the extremely misleading & incorrect comments:

<code>
#define     STRICT
#define     UNICODE
#include <windows.h>
#include <stdexcept>

bool throwX( char const s[] ) { throw std::runtime_error( s ); }

wchar_t const windowClassName[] = L"BasicApp";
wchar_t const windowTitle[]     = L"A Simple Window";

LRESULT CALLBACK windowProcedure(
     HWND windowHandle, UINT msg_id, WPARAM wParam, LPARAM lParam
     )
{
     switch( msg_id )
     {
     case WM_DESTROY:                    // Window is being destroyed.
         PostQuitMessage( WM_QUIT );     // Terminates message loop.
         break;
     default:
         return DefWindowProc( windowHandle, msg_id, wParam, lParam );
     }
     return 0;
}

void registerWindowClass()
{
     WNDCLASSEX  info    = { sizeof( WNDCLASSEX ) };

     info.style          = CS_HREDRAW | CS_VREDRAW;
     info.lpfnWndProc    = windowProcedure;
     info.hIcon          = LoadIcon( 0, IDI_APPLICATION );
     info.hCursor        = LoadCursor( 0, IDC_ARROW );
     info.hbrBackground  = reinterpret_cast<HBRUSH>( COLOR_WINDOW + 1 );
     info.lpszClassName  = windowClassName;
     info.hInstance      = GetModuleHandle( 0 );
     info.hIconSm        = LoadIcon( 0, IDI_APPLICATION );
     RegisterClassEx( &info ) || throwX( "RegisterClassEx failed" );
}

HWND createMainWindow()
{
     HWND const handle = CreateWindow(
         windowClassName,
         windowTitle,
         WS_OVERLAPPEDWINDOW,
         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
         0,
         0,
         GetModuleHandle( 0 ),
         0
         );
     handle != 0 || throwX( "CreateWindow failed" );
     return handle;
}

void processMessages()
{
     MSG msg;
     while( GetMessage( &msg, 0, 0, 0 ) > 0 )
     {
         TranslateMessage( &msg );
         DispatchMessage( &msg );
     }
}

void cppMain()
{
     registerWindowClass();
     ShowWindow( createMainWindow(), SW_SHOWNORMAL );
     processMessages();
}

int main()
{
     try
     {
         cppMain();
         return EXIT_SUCCESS;
     }
     catch( std::exception const& )
     {
         return EXIT_FAILURE;
     }
}
</code>

Note to OP: the GNU toolchain's linker is happy with the standard 'main' also 
for a GUI subsystem application, but Microsoft's tools are geared towards more 
non-standard behavior, so for a GUI subsystem app, in the project properties you 
may have to specify '/entry:mainCRTStartup' (linker option).



Cheers & hth.,

- Alf
0
Reply Alf 4/5/2010 2:12:46 AM


"Alf P. Steinbach" <alfps@start.no> wrote in message 
news:hpbh2d$d5i$1@news.eternal-september.org...
> * Leigh Johnston:
>> * Leigh Johnston:
>>> * Tauqir:
>>>>
>>>> I am trying a very simple windows tutorial, all code is from the
>>>> tutorial but at compile time it is giving the above error. I am using
>>>> Visual Studio 2008 C++, starting with an empty project, Here is the
>>>> code:
>>>> Any ideas, where is this function _tmainCETStartup coming in from and
>>>> where should be what it is looking for?
> [snip code]
>>>
>>> Try creating the project again but this time choose "Win32 Project / 
>>> Windows Application" and not "Win32 Console Application / Console 
>>> Application".
>>
>> After doing that ensure you use the following for "WinMain":
>>
>> int APIENTRY _tWinMain(HINSTANCE hInstance,
>>                     HINSTANCE hPrevInstance,
>>                     LPTSTR    lpCmdLine,
>>                     int       nCmdShow)
>> {
>> }
>>
>> Especially important is the LPTSTR to avoid Unicode/ANSI problems 
>> although the linker might be forgiving.
>
> Tauqir: evidently you mistyped the name of the missing function. I presume 
> it was 'mainCRTStartup'.
>
> 'mainCRTStartup' is one of several Microsoft runtime library functions 
> that can be used as your program's entry point, where the execution 
> starts. This particular function calls a standard C or C++ 'main' 
> function, which you are supposed to define. The others call other 
> non-standard startup functions such as WinMain.
>
> With Microsoft's toolchain one way to specify which entry point function 
> to use is to choose the right project type in Visual Studio, as Leigh 
> advised. Ultimately that translates down to an /entry option being passed 
> to the linker, or no such option (for the default). The determination of a 
> default is intricate and as far as I know not documented, so to take 
> charge, when you want to do that, you need to use /entry (it can be 
> specified in the project settings).
>
> Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like 
> "we all know that" among many Windows programmers. However, it's advice 
> that once (early to middle 90's) was great, but which after that is wrong, 
> perpetuated by bad Microsoft code examples and copycat programming & 
> teaching. It's like advice talking about proper care of horses in order to 
> help you drive safely to work.
>
> First, the OP's code uses plain Unicode string like L"ouch", which means 
> the source will only compile with one setting of T-stuff, namely Unicode.
>
> Secondly, supporting Windows 9x, which the T-stuff is about, is as of 2010 
> not worth the effort.
>
> Third, except when using MFC the way to go for supporting Unicode in 
> Windows 9x (if some evil manager requires that) is to use Microsoft's 
> Layer for Unicode.
>
> In short, T-stuff is just silly and adds a lot of needless work, and if 
> one absolutely feels that one must use a Microsoft specific startup 
> function instead of standard 'main', then that should be 'wMain' or 
> 'wWinMain' (Unicode).
>

I mentioned the need that "WinMain" should use LPTSTR instead of LPSTR as 
the use of L"" elsewhere in the code suggests a Unicode build which would 
mean you would not be able to access any program arguments without a cast so 
it is not a "silly" suggestion.  A valid alternative would be to use LPWSTR 
but it is important to be consistent IMO.  I agree that non-Unicode builds 
in this day and age are a rare thing.

/Leigh 

0
Reply Leigh 4/5/2010 10:40:20 AM


"Leigh Johnston" <leigh@i42.co.uk> wrote in message 
news:2qOdnWgTNsiJIyTWnZ2dnUVZ8tmdnZ2d@giganews.com...
>
>
> "Alf P. Steinbach" <alfps@start.no> wrote in message 
> news:hpbh2d$d5i$1@news.eternal-september.org...
>> * Leigh Johnston:
>>> * Leigh Johnston:
>>>> * Tauqir:
>>>>>
>>>>> I am trying a very simple windows tutorial, all code is from the
>>>>> tutorial but at compile time it is giving the above error. I am using
>>>>> Visual Studio 2008 C++, starting with an empty project, Here is the
>>>>> code:
>>>>> Any ideas, where is this function _tmainCETStartup coming in from and
>>>>> where should be what it is looking for?
>> [snip code]
>>>>
>>>> Try creating the project again but this time choose "Win32 Project / 
>>>> Windows Application" and not "Win32 Console Application / Console 
>>>> Application".
>>>
>>> After doing that ensure you use the following for "WinMain":
>>>
>>> int APIENTRY _tWinMain(HINSTANCE hInstance,
>>>                     HINSTANCE hPrevInstance,
>>>                     LPTSTR    lpCmdLine,
>>>                     int       nCmdShow)
>>> {
>>> }
>>>
>>> Especially important is the LPTSTR to avoid Unicode/ANSI problems 
>>> although the linker might be forgiving.
>>
>> Tauqir: evidently you mistyped the name of the missing function. I 
>> presume it was 'mainCRTStartup'.
>>
>> 'mainCRTStartup' is one of several Microsoft runtime library functions 
>> that can be used as your program's entry point, where the execution 
>> starts. This particular function calls a standard C or C++ 'main' 
>> function, which you are supposed to define. The others call other 
>> non-standard startup functions such as WinMain.
>>
>> With Microsoft's toolchain one way to specify which entry point function 
>> to use is to choose the right project type in Visual Studio, as Leigh 
>> advised. Ultimately that translates down to an /entry option being passed 
>> to the linker, or no such option (for the default). The determination of 
>> a default is intricate and as far as I know not documented, so to take 
>> charge, when you want to do that, you need to use /entry (it can be 
>> specified in the project settings).
>>
>> Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like 
>> "we all know that" among many Windows programmers. However, it's advice 
>> that once (early to middle 90's) was great, but which after that is 
>> wrong, perpetuated by bad Microsoft code examples and copycat programming 
>> & teaching. It's like advice talking about proper care of horses in order 
>> to help you drive safely to work.
>>
>> First, the OP's code uses plain Unicode string like L"ouch", which means 
>> the source will only compile with one setting of T-stuff, namely Unicode.
>>
>> Secondly, supporting Windows 9x, which the T-stuff is about, is as of 
>> 2010 not worth the effort.
>>
>> Third, except when using MFC the way to go for supporting Unicode in 
>> Windows 9x (if some evil manager requires that) is to use Microsoft's 
>> Layer for Unicode.
>>
>> In short, T-stuff is just silly and adds a lot of needless work, and if 
>> one absolutely feels that one must use a Microsoft specific startup 
>> function instead of standard 'main', then that should be 'wMain' or 
>> 'wWinMain' (Unicode).
>>
>
> I mentioned the need that "WinMain" should use LPTSTR instead of LPSTR as 
> the use of L"" elsewhere in the code suggests a Unicode build which would 
> mean you would not be able to access any program arguments without a cast 
> so it is not a "silly" suggestion.  A valid alternative would be to use 
> LPWSTR but it is important to be consistent IMO.  I agree that non-Unicode 
> builds in this day and age are a rare thing.
>
> /Leigh

Actually I am in error so ignore that because if you don't use the w prefix 
versions of WinMain/main it seems that VC++ is clever enough to do the right 
thing.

/Leigh 

0
Reply Leigh 4/5/2010 10:48:32 AM


"Leigh Johnston" <leigh@i42.co.uk> wrote in message 
news:7eOdnap1JMCdXSTWnZ2dnUVZ8uqdnZ2d@giganews.com...
>
>> I mentioned the need that "WinMain" should use LPTSTR instead of LPSTR as 
>> the use of L"" elsewhere in the code suggests a Unicode build which would 
>> mean you would not be able to access any program arguments without a cast 
>> so it is not a "silly" suggestion.  A valid alternative would be to use 
>> LPWSTR but it is important to be consistent IMO.  I agree that 
>> non-Unicode builds in this day and age are a rare thing.
>>
>> /Leigh
>
> Actually I am in error so ignore that because if you don't use the w 
> prefix versions of WinMain/main it seems that VC++ is clever enough to do 
> the right thing.
>

By "do the right thing" I meant that the non-wide versions of main/WinMain 
will have narrow program arguments even in a Unicode build so no cast would 
be required however if you want Unicode (UTF-16) program arguments (which is 
highly likely this day and age) then the wide prefix versions of 
main/WinMain should be used and using _t and LPTSTR is a standard Microsoft 
way of doing this still as illustrated by the fact that VS2008 project 
wizard still creates new projects using them.

/Leigh 

0
Reply Leigh 4/5/2010 11:17:56 AM


"Alf P. Steinbach" <alfps@start.no> wrote in message 
news:hpbh2d$d5i$1@news.eternal-september.org...
> * Leigh Johnston:
>> * Leigh Johnston:
>>> * Tauqir:
>>>>
>>>> I am trying a very simple windows tutorial, all code is from the
>>>> tutorial but at compile time it is giving the above error. I am using
>>>> Visual Studio 2008 C++, starting with an empty project, Here is the
>>>> code:
>>>> Any ideas, where is this function _tmainCETStartup coming in from and
>>>> where should be what it is looking for?
> [snip code]
>>>
>>> Try creating the project again but this time choose "Win32 Project / 
>>> Windows Application" and not "Win32 Console Application / Console 
>>> Application".
>>
>> After doing that ensure you use the following for "WinMain":
>>
>> int APIENTRY _tWinMain(HINSTANCE hInstance,
>>                     HINSTANCE hPrevInstance,
>>                     LPTSTR    lpCmdLine,
>>                     int       nCmdShow)
>> {
>> }
>>
>> Especially important is the LPTSTR to avoid Unicode/ANSI problems 
>> although the linker might be forgiving.
>
> Tauqir: evidently you mistyped the name of the missing function. I presume 
> it was 'mainCRTStartup'.
>
> 'mainCRTStartup' is one of several Microsoft runtime library functions 
> that can be used as your program's entry point, where the execution 
> starts. This particular function calls a standard C or C++ 'main' 
> function, which you are supposed to define. The others call other 
> non-standard startup functions such as WinMain.
>
> With Microsoft's toolchain one way to specify which entry point function 
> to use is to choose the right project type in Visual Studio, as Leigh 
> advised. Ultimately that translates down to an /entry option being passed 
> to the linker, or no such option (for the default). The determination of a 
> default is intricate and as far as I know not documented, so to take 
> charge, when you want to do that, you need to use /entry (it can be 
> specified in the project settings).
>
> Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like 
> "we all know that" among many Windows programmers. However, it's advice 
> that once (early to middle 90's) was great, but which after that is wrong, 
> perpetuated by bad Microsoft code examples and copycat programming & 
> teaching. It's like advice talking about proper care of horses in order to 
> help you drive safely to work.
>
> First, the OP's code uses plain Unicode string like L"ouch", which means 
> the source will only compile with one setting of T-stuff, namely Unicode.
>
> Secondly, supporting Windows 9x, which the T-stuff is about, is as of 2010 
> not worth the effort.
>
> Third, except when using MFC the way to go for supporting Unicode in 
> Windows 9x (if some evil manager requires that) is to use Microsoft's 
> Layer for Unicode.
>
> In short, T-stuff is just silly and adds a lot of needless work, and if 
> one absolutely feels that one must use a Microsoft specific startup 
> function instead of standard 'main', then that should be 'wMain' or 
> 'wWinMain' (Unicode).
>
> Here's the OP's code reworked to less Microsoft'isms, less C'isms, and 
> without the extremely misleading & incorrect comments:
>
> <code>
> #define     STRICT
> #define     UNICODE
> #include <windows.h>
> #include <stdexcept>
>
> bool throwX( char const s[] ) { throw std::runtime_error( s ); }
>
> wchar_t const windowClassName[] = L"BasicApp";
> wchar_t const windowTitle[]     = L"A Simple Window";
>
> LRESULT CALLBACK windowProcedure(
>     HWND windowHandle, UINT msg_id, WPARAM wParam, LPARAM lParam
>     )
> {
>     switch( msg_id )
>     {
>     case WM_DESTROY:                    // Window is being destroyed.
>         PostQuitMessage( WM_QUIT );     // Terminates message loop.
>         break;
>     default:
>         return DefWindowProc( windowHandle, msg_id, wParam, lParam );
>     }
>     return 0;
> }
>
> void registerWindowClass()
> {
>     WNDCLASSEX  info    = { sizeof( WNDCLASSEX ) };
>
>     info.style          = CS_HREDRAW | CS_VREDRAW;
>     info.lpfnWndProc    = windowProcedure;
>     info.hIcon          = LoadIcon( 0, IDI_APPLICATION );
>     info.hCursor        = LoadCursor( 0, IDC_ARROW );
>     info.hbrBackground  = reinterpret_cast<HBRUSH>( COLOR_WINDOW + 1 );
>     info.lpszClassName  = windowClassName;
>     info.hInstance      = GetModuleHandle( 0 );
>     info.hIconSm        = LoadIcon( 0, IDI_APPLICATION );
>     RegisterClassEx( &info ) || throwX( "RegisterClassEx failed" );
> }
>
> HWND createMainWindow()
> {
>     HWND const handle = CreateWindow(
>         windowClassName,
>         windowTitle,
>         WS_OVERLAPPEDWINDOW,
>         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
>         0,
>         0,
>         GetModuleHandle( 0 ),
>         0
>         );
>     handle != 0 || throwX( "CreateWindow failed" );
>     return handle;
> }
>
> void processMessages()
> {
>     MSG msg;
>     while( GetMessage( &msg, 0, 0, 0 ) > 0 )
>     {
>         TranslateMessage( &msg );
>         DispatchMessage( &msg );
>     }
> }
>
> void cppMain()
> {
>     registerWindowClass();
>     ShowWindow( createMainWindow(), SW_SHOWNORMAL );
>     processMessages();
> }
>
> int main()
> {
>     try
>     {
>         cppMain();
>         return EXIT_SUCCESS;
>     }
>     catch( std::exception const& )
>     {
>         return EXIT_FAILURE;
>     }
> }
> </code>
>
> Note to OP: the GNU toolchain's linker is happy with the standard 'main' 
> also for a GUI subsystem application, but Microsoft's tools are geared 
> towards more non-standard behavior, so for a GUI subsystem app, in the 
> project properties you may have to specify '/entry:mainCRTStartup' (linker 
> option).
>
>
>
> Cheers & hth.,
>
> - Alf
>

One should use WinMain not main when implementing GUI (not console) apps 
otherwise you cannot benefit from knowing the value of nCmdShow for example. 
FWIW I tend to use std::string/std::wstring where appropriate (mainly in my 
lower level engine code) but for the higher level GUI code I sometimes use 
LPTSTR, LPWSTR, LPSTR et al where it makes sense for WINAPI interop or for 
character width agnostic GUI control implementations.

/Leigh 

0
Reply Leigh 4/5/2010 12:10:31 PM


"Leigh Johnston" <leigh@i42.co.uk> wrote in message 
news:Jsadne5ZSN6nTiTWnZ2dnUVZ8uOdnZ2d@giganews.com...
>
>
> "Alf P. Steinbach" <alfps@start.no> wrote in message 
> news:hpbh2d$d5i$1@news.eternal-september.org...
>> * Leigh Johnston:
>>> * Leigh Johnston:
>>>> * Tauqir:
>>>>>
>>>>> I am trying a very simple windows tutorial, all code is from the
>>>>> tutorial but at compile time it is giving the above error. I am using
>>>>> Visual Studio 2008 C++, starting with an empty project, Here is the
>>>>> code:
>>>>> Any ideas, where is this function _tmainCETStartup coming in from and
>>>>> where should be what it is looking for?
>> [snip code]
>>>>
>>>> Try creating the project again but this time choose "Win32 Project / 
>>>> Windows Application" and not "Win32 Console Application / Console 
>>>> Application".
>>>
>>> After doing that ensure you use the following for "WinMain":
>>>
>>> int APIENTRY _tWinMain(HINSTANCE hInstance,
>>>                     HINSTANCE hPrevInstance,
>>>                     LPTSTR    lpCmdLine,
>>>                     int       nCmdShow)
>>> {
>>> }
>>>
>>> Especially important is the LPTSTR to avoid Unicode/ANSI problems 
>>> although the linker might be forgiving.
>>
>> Tauqir: evidently you mistyped the name of the missing function. I 
>> presume it was 'mainCRTStartup'.
>>
>> 'mainCRTStartup' is one of several Microsoft runtime library functions 
>> that can be used as your program's entry point, where the execution 
>> starts. This particular function calls a standard C or C++ 'main' 
>> function, which you are supposed to define. The others call other 
>> non-standard startup functions such as WinMain.
>>
>> With Microsoft's toolchain one way to specify which entry point function 
>> to use is to choose the right project type in Visual Studio, as Leigh 
>> advised. Ultimately that translates down to an /entry option being passed 
>> to the linker, or no such option (for the default). The determination of 
>> a default is intricate and as far as I know not documented, so to take 
>> charge, when you want to do that, you need to use /entry (it can be 
>> specified in the project settings).
>>
>> Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like 
>> "we all know that" among many Windows programmers. However, it's advice 
>> that once (early to middle 90's) was great, but which after that is 
>> wrong, perpetuated by bad Microsoft code examples and copycat programming 
>> & teaching. It's like advice talking about proper care of horses in order 
>> to help you drive safely to work.
>>
>> First, the OP's code uses plain Unicode string like L"ouch", which means 
>> the source will only compile with one setting of T-stuff, namely Unicode.
>>
>> Secondly, supporting Windows 9x, which the T-stuff is about, is as of 
>> 2010 not worth the effort.
>>
>> Third, except when using MFC the way to go for supporting Unicode in 
>> Windows 9x (if some evil manager requires that) is to use Microsoft's 
>> Layer for Unicode.
>>
>> In short, T-stuff is just silly and adds a lot of needless work, and if 
>> one absolutely feels that one must use a Microsoft specific startup 
>> function instead of standard 'main', then that should be 'wMain' or 
>> 'wWinMain' (Unicode).
>>
>> Here's the OP's code reworked to less Microsoft'isms, less C'isms, and 
>> without the extremely misleading & incorrect comments:
>>
>> <code>
>> #define     STRICT
>> #define     UNICODE
>> #include <windows.h>
>> #include <stdexcept>
>>
>> bool throwX( char const s[] ) { throw std::runtime_error( s ); }
>>
>> wchar_t const windowClassName[] = L"BasicApp";
>> wchar_t const windowTitle[]     = L"A Simple Window";
>>
>> LRESULT CALLBACK windowProcedure(
>>     HWND windowHandle, UINT msg_id, WPARAM wParam, LPARAM lParam
>>     )
>> {
>>     switch( msg_id )
>>     {
>>     case WM_DESTROY:                    // Window is being destroyed.
>>         PostQuitMessage( WM_QUIT );     // Terminates message loop.
>>         break;
>>     default:
>>         return DefWindowProc( windowHandle, msg_id, wParam, lParam );
>>     }
>>     return 0;
>> }
>>
>> void registerWindowClass()
>> {
>>     WNDCLASSEX  info    = { sizeof( WNDCLASSEX ) };
>>
>>     info.style          = CS_HREDRAW | CS_VREDRAW;
>>     info.lpfnWndProc    = windowProcedure;
>>     info.hIcon          = LoadIcon( 0, IDI_APPLICATION );
>>     info.hCursor        = LoadCursor( 0, IDC_ARROW );
>>     info.hbrBackground  = reinterpret_cast<HBRUSH>( COLOR_WINDOW + 1 );
>>     info.lpszClassName  = windowClassName;
>>     info.hInstance      = GetModuleHandle( 0 );
>>     info.hIconSm        = LoadIcon( 0, IDI_APPLICATION );
>>     RegisterClassEx( &info ) || throwX( "RegisterClassEx failed" );
>> }
>>
>> HWND createMainWindow()
>> {
>>     HWND const handle = CreateWindow(
>>         windowClassName,
>>         windowTitle,
>>         WS_OVERLAPPEDWINDOW,
>>         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
>>         0,
>>         0,
>>         GetModuleHandle( 0 ),
>>         0
>>         );
>>     handle != 0 || throwX( "CreateWindow failed" );
>>     return handle;
>> }
>>
>> void processMessages()
>> {
>>     MSG msg;
>>     while( GetMessage( &msg, 0, 0, 0 ) > 0 )
>>     {
>>         TranslateMessage( &msg );
>>         DispatchMessage( &msg );
>>     }
>> }
>>
>> void cppMain()
>> {
>>     registerWindowClass();
>>     ShowWindow( createMainWindow(), SW_SHOWNORMAL );
>>     processMessages();
>> }
>>
>> int main()
>> {
>>     try
>>     {
>>         cppMain();
>>         return EXIT_SUCCESS;
>>     }
>>     catch( std::exception const& )
>>     {
>>         return EXIT_FAILURE;
>>     }
>> }
>> </code>
>>
>> Note to OP: the GNU toolchain's linker is happy with the standard 'main' 
>> also for a GUI subsystem application, but Microsoft's tools are geared 
>> towards more non-standard behavior, so for a GUI subsystem app, in the 
>> project properties you may have to specify '/entry:mainCRTStartup' 
>> (linker option).
>>
>>
>>
>> Cheers & hth.,
>>
>> - Alf
>>
>
> One should use WinMain not main when implementing GUI (not console) apps 
> otherwise you cannot benefit from knowing the value of nCmdShow for 
> example. FWIW I tend to use std::string/std::wstring where appropriate 
> (mainly in my lower level engine code) but for the higher level GUI code I 
> sometimes use LPTSTR, LPWSTR, LPSTR et al where it makes sense for WINAPI 
> interop or for character width agnostic GUI control implementations.
>
> /Leigh

Yes I know there is GetStartupInfo() but I still think eschewing WinMain() 
is bad advice for Windows C++ GUI apps.

/Leigh 

0
Reply Leigh 4/5/2010 12:27:47 PM


"Leigh Johnston" <leigh@i42.co.uk> wrote in message 
news:1OSdnTx0ELHbSiTWnZ2dnUVZ8tqdnZ2d@giganews.com...
>> One should use WinMain not main when implementing GUI (not console) apps 
>> otherwise you cannot benefit from knowing the value of nCmdShow for 
>> example. FWIW I tend to use std::string/std::wstring where appropriate 
>> (mainly in my lower level engine code) but for the higher level GUI code 
>> I sometimes use LPTSTR, LPWSTR, LPSTR et al where it makes sense for 
>> WINAPI interop or for character width agnostic GUI control 
>> implementations.
>>
>> /Leigh
>
> Yes I know there is GetStartupInfo() but I still think eschewing WinMain() 
> is bad advice for Windows C++ GUI apps.
>

Oh and there is SW_SHOWDEFAULT as well which I forgot about but as far as I 
know Microsoft has not deprecated WinMain().

/Leigh 

0
Reply Leigh 4/5/2010 12:31:54 PM

"Leigh Johnston" <leigh@i42.co.uk> wrote in
news:2qOdnWgTNsiJIyTWnZ2dnUVZ8tmdnZ2d@giganews.com: 

>  I
> agree that non-Unicode builds in this day and age are a rare thing.

That's true, most apps should use Unicode encoding where appropriate. 
However, this has little to do with UNICODE compilation mode and the 
plethora of other macros invented by Microsoft. For Unicode it is not 
necessary to use the UNICODE macro, which just enforces a given Unicode 
compressed format (UTF-16). Using UTF-8 would be an equally valid 
alternative, especially in portable projects. Unfortunately Windows does 
not support UTF-8 locales, so for Windows-only projects UTF-16 is working 
smoother.

There is no need for T, LPCSTR etc. macros in any case, I see no reason for 
their existance, at least nowadays. For example, if my strings are all UTF-
8 internally, then my Windows interfacing code will look like:

std::string content_u8 = ...;
::MessageBoxW(hwnd, Utf2Win(content_u8).c_str(), L"Warning", MB_OK);

The custom Utf2Win() function (wrapping MultiByteToWideChar()) is 
performing the needed translation from UTF-8 to UTF-16 on the application 
border. Note that this code does not need nor care about the UNICODE macro 
and does not use any "T" macros.

cheers
Paavo


0
Reply Paavo 4/5/2010 7:54:26 PM


"Paavo Helde" <myfirstname@osa.pri.ee> wrote in message 
news:Xns9D51E95CB54E0paavo256@216.196.109.131...
> "Leigh Johnston" <leigh@i42.co.uk> wrote in
> news:2qOdnWgTNsiJIyTWnZ2dnUVZ8tmdnZ2d@giganews.com:
>
>>  I
>> agree that non-Unicode builds in this day and age are a rare thing.
>
> That's true, most apps should use Unicode encoding where appropriate.
> However, this has little to do with UNICODE compilation mode and the
> plethora of other macros invented by Microsoft. For Unicode it is not
> necessary to use the UNICODE macro, which just enforces a given Unicode
> compressed format (UTF-16). Using UTF-8 would be an equally valid
> alternative, especially in portable projects. Unfortunately Windows does
> not support UTF-8 locales, so for Windows-only projects UTF-16 is working
> smoother.
>
> There is no need for T, LPCSTR etc. macros in any case, I see no reason 
> for
> their existance, at least nowadays. For example, if my strings are all 
> UTF-
> 8 internally, then my Windows interfacing code will look like:
>
> std::string content_u8 = ...;
> ::MessageBoxW(hwnd, Utf2Win(content_u8).c_str(), L"Warning", MB_OK);
>
> The custom Utf2Win() function (wrapping MultiByteToWideChar()) is
> performing the needed translation from UTF-8 to UTF-16 on the application
> border. Note that this code does not need nor care about the UNICODE macro
> and does not use any "T" macros.
>

Yeah I agree, I do something similar as I prefer UTF-8 to UTF-16 also and 
convert where required (e.g. reading from / writing to a control) so I tend 
to have a lot more std::string than std::wstring in my projects.  However I 
also use MFC a lot and when overriding the following virtual function:

void CDocument::SetTitle(LPCTSTR lpszTitle);

I would feel uncomfortable writing:

void CMyDocument::SetTitle(wchar_t* lpszTitle);

So I still use the T macros in places.

/Leigh
 

0
Reply Leigh 4/5/2010 8:05:59 PM


"Leigh Johnston" <leigh@i42.co.uk> wrote in message 
news:Mf6dnantFOsq3yfWnZ2dnUVZ8jWdnZ2d@giganews.com...
>
> void CMyDocument::SetTitle(wchar_t* lpszTitle);
>

That should have been "(const wchar_t* lpszTitle)" of course. :)

/Leigh 

0
Reply Leigh 4/5/2010 8:07:57 PM

On Apr 4, 7:12=A0pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * Leigh Johnston:
>
>
>
>
>
> > * Leigh Johnston:
> >> * Tauqir:
>
> >>> I am trying a very simple windows tutorial, all code is from the
> >>> tutorial but at compile time it is giving the above error. I am using
> >>> Visual Studio 2008 C++, starting with an empty project, Here is the
> >>> code:
> >>> Any ideas, where is this function _tmainCETStartup coming in from and
> >>> where should be what it is looking for?
> [snip code]
>
> >> Try creating the project again but this time choose "Win32 Project /
> >> Windows Application" and not "Win32 Console Application / Console
> >> Application".
>
> > After doing that ensure you use the following for "WinMain":
>
> > int APIENTRY _tWinMain(HINSTANCE hInstance,
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 HINSTANCE hPrevInstance,
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 LPTSTR =A0 =A0lpCmdLine,
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int =A0 =A0 =A0 nCmdShow)
> > {
> > }
>
> > Especially important is the LPTSTR to avoid Unicode/ANSI problems
> > although the linker might be forgiving.
>
> Tauqir: evidently you mistyped the name of the missing function. I presum=
e it
> was 'mainCRTStartup'.
>
> 'mainCRTStartup' is one of several Microsoft runtime library functions th=
at can
> be used as your program's entry point, where the execution starts. This
> particular function calls a standard C or C++ 'main' function, which you =
are
> supposed to define. The others call other non-standard startup functions =
such as
> WinMain.
>
> With Microsoft's toolchain one way to specify which entry point function =
to use
> is to choose the right project type in Visual Studio, as Leigh advised.
> Ultimately that translates down to an /entry option being passed to the l=
inker,
> or no such option (for the default). The determination of a default is in=
tricate
> and as far as I know not documented, so to take charge, when you want to =
do
> that, you need to use /entry (it can be specified in the project settings=
).
>
> Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like=
 "we
> all know that" among many Windows programmers. However, it's advice that =
once
> (early to middle 90's) was great, but which after that is wrong, perpetua=
ted by
> bad Microsoft code examples and copycat programming & teaching. It's like=
 advice
> talking about proper care of horses in order to help you drive safely to =
work.
>
> First, the OP's code uses plain Unicode string like L"ouch", which means =
the
> source will only compile with one setting of T-stuff, namely Unicode.
>
> Secondly, supporting Windows 9x, which the T-stuff is about, is as of 201=
0 not
> worth the effort.
>
> Third, except when using MFC the way to go for supporting Unicode in Wind=
ows 9x
> (if some evil manager requires that) is to use Microsoft's Layer for Unic=
ode.
>
> In short, T-stuff is just silly and adds a lot of needless work, and if o=
ne
> absolutely feels that one must use a Microsoft specific startup function =
instead
> of standard 'main', then that should be 'wMain' or 'wWinMain' (Unicode).
>
> Here's the OP's code reworked to less Microsoft'isms, less C'isms, and wi=
thout
> the extremely misleading & incorrect comments:
>
> <code>
> #define =A0 =A0 STRICT
> #define =A0 =A0 UNICODE
> #include <windows.h>
> #include <stdexcept>
>
> bool throwX( char const s[] ) { throw std::runtime_error( s ); }
>
> wchar_t const windowClassName[] =3D L"BasicApp";
> wchar_t const windowTitle[] =A0 =A0 =3D L"A Simple Window";
>
> LRESULT CALLBACK windowProcedure(
> =A0 =A0 =A0HWND windowHandle, UINT msg_id, WPARAM wParam, LPARAM lParam
> =A0 =A0 =A0)
> {
> =A0 =A0 =A0switch( msg_id )
> =A0 =A0 =A0{
> =A0 =A0 =A0case WM_DESTROY: =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0// Win=
dow is being destroyed.
> =A0 =A0 =A0 =A0 =A0PostQuitMessage( WM_QUIT ); =A0 =A0 // Terminates mess=
age loop.
> =A0 =A0 =A0 =A0 =A0break;
> =A0 =A0 =A0default:
> =A0 =A0 =A0 =A0 =A0return DefWindowProc( windowHandle, msg_id, wParam, lP=
aram );
> =A0 =A0 =A0}
> =A0 =A0 =A0return 0;
>
> }
>
> void registerWindowClass()
> {
> =A0 =A0 =A0WNDCLASSEX =A0info =A0 =A0=3D { sizeof( WNDCLASSEX ) };
>
> =A0 =A0 =A0info.style =A0 =A0 =A0 =A0 =A0=3D CS_HREDRAW | CS_VREDRAW;
> =A0 =A0 =A0info.lpfnWndProc =A0 =A0=3D windowProcedure;
> =A0 =A0 =A0info.hIcon =A0 =A0 =A0 =A0 =A0=3D LoadIcon( 0, IDI_APPLICATION=
 );
> =A0 =A0 =A0info.hCursor =A0 =A0 =A0 =A0=3D LoadCursor( 0, IDC_ARROW );
> =A0 =A0 =A0info.hbrBackground =A0=3D reinterpret_cast<HBRUSH>( COLOR_WIND=
OW + 1 );
> =A0 =A0 =A0info.lpszClassName =A0=3D windowClassName;
> =A0 =A0 =A0info.hInstance =A0 =A0 =A0=3D GetModuleHandle( 0 );
> =A0 =A0 =A0info.hIconSm =A0 =A0 =A0 =A0=3D LoadIcon( 0, IDI_APPLICATION )=
;
> =A0 =A0 =A0RegisterClassEx( &info ) || throwX( "RegisterClassEx failed" )=
;
>
> }
>
> HWND createMainWindow()
> {
> =A0 =A0 =A0HWND const handle =3D CreateWindow(
> =A0 =A0 =A0 =A0 =A0windowClassName,
> =A0 =A0 =A0 =A0 =A0windowTitle,
> =A0 =A0 =A0 =A0 =A0WS_OVERLAPPEDWINDOW,
> =A0 =A0 =A0 =A0 =A0CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEF=
AULT,
> =A0 =A0 =A0 =A0 =A00,
> =A0 =A0 =A0 =A0 =A00,
> =A0 =A0 =A0 =A0 =A0GetModuleHandle( 0 ),
> =A0 =A0 =A0 =A0 =A00
> =A0 =A0 =A0 =A0 =A0);
> =A0 =A0 =A0handle !=3D 0 || throwX( "CreateWindow failed" );
> =A0 =A0 =A0return handle;
>
> }
>
> void processMessages()
> {
> =A0 =A0 =A0MSG msg;
> =A0 =A0 =A0while( GetMessage( &msg, 0, 0, 0 ) > 0 )
> =A0 =A0 =A0{
> =A0 =A0 =A0 =A0 =A0TranslateMessage( &msg );
> =A0 =A0 =A0 =A0 =A0DispatchMessage( &msg );
> =A0 =A0 =A0}
>
> }
>
> void cppMain()
> {
> =A0 =A0 =A0registerWindowClass();
> =A0 =A0 =A0ShowWindow( createMainWindow(), SW_SHOWNORMAL );
> =A0 =A0 =A0processMessages();
>
> }
>
> int main()
> {
> =A0 =A0 =A0try
> =A0 =A0 =A0{
> =A0 =A0 =A0 =A0 =A0cppMain();
> =A0 =A0 =A0 =A0 =A0return EXIT_SUCCESS;
> =A0 =A0 =A0}
> =A0 =A0 =A0catch( std::exception const& )
> =A0 =A0 =A0{
> =A0 =A0 =A0 =A0 =A0return EXIT_FAILURE;
> =A0 =A0 =A0}}
>
> </code>
>
> Note to OP: the GNU toolchain's linker is happy with the standard 'main' =
also
> for a GUI subsystem application, but Microsoft's tools are geared towards=
 more
> non-standard behavior, so for a GUI subsystem app, in the project propert=
ies you
> may have to specify '/entry:mainCRTStartup' (linker option).
>
> Cheers & hth.,
>
> - Alf- Hide quoted text -
>
> - Show quoted text -

Guys, Thanks very much,
I started with the Win32Project / Windows application and of course
the startup project does give me a working starting point with
_tWinMain as the windows APIENTRY point.
Interestingly Unicode is at the core of my work. Purpose is to make a
simplest unicode editor for my native language,'Urdu'. A lot of people
type Urdu in English script and I just cannot stand it.
I initailly started with C Sharp, but was unable to get the client
area where users encoded strings will be displayed. Only option was to
use the Rich Text control, but that was rather limiting, because it
had to be on a form.
Now my challenge is to read user input (c=3Dgetchar()? )-  based on a
keyboard mapping - encode the character in Urdu and display
(putchar(c) )it in the Arial Unicode MS, which is shipped with Windows
XP. No Windows 98 consideration.
My C++ skills are at this moment rusted. A few lines of code to get
this done will be a great boost at this time.

Tauqir


0
Reply Tauqir 4/9/2010 8:32:47 AM

Tauqir <tauqirghani@yahoo.com> wrote in
news:bedf6ef2-64a4-4409-ad96-0af608a28a92@11g2000yqr.googlegroups.com: 

> Interestingly Unicode is at the core of my work. Purpose is to make a
> simplest unicode editor for my native language,'Urdu'. A lot of people
> type Urdu in English script and I just cannot stand it.
> I initailly started with C Sharp, but was unable to get the client
> area where users encoded strings will be displayed. Only option was to
> use the Rich Text control, but that was rather limiting, because it
> had to be on a form.

You might be interested in the Scintilla editor control 
(www.scintilla.org). This can be used as a text editor view, there are lots 
of features and the lexer variant has syntax highlighting options. We are 
using it in our own project with Arial Unicode font for editing UTF-8 
encoded text files, it is working very nicely.

hth
Paavo


0
Reply Paavo 4/9/2010 4:01:09 PM

14 Replies
812 Views

(page loaded in 0.174 seconds)

Similiar Articles:




7/24/2012 6:58:32 AM


Reply: