Jump to page: 1 2
Thread overview
Why is the Win32 boilerplate the way it is?
Jun 29, 2014
Jeremy Sorensen
Jun 29, 2014
Jacob Carlborg
Jun 29, 2014
Jeremy Sorensen
Jun 29, 2014
Trass3r
Jun 29, 2014
Jacob Carlborg
Jun 30, 2014
Jeremy Sorensen
Jul 02, 2014
Vladimir Panteleev
Jun 30, 2014
Jeremy Sorensen
Jun 30, 2014
Jason King
Jun 30, 2014
Jeremy Sorensen
Jun 30, 2014
Adam D. Ruppe
Jun 30, 2014
Jason King
Jul 02, 2014
Vladimir Panteleev
Jul 01, 2014
Jeremy Sorensen
June 29, 2014
I found an example of boilerplate code for Win32 programming in D here:
http://wiki.dlang.org/D_for_Win32

I have some questions.
1. It appears that the call to myWinMain from WinMain is to ensure that any exception or error is caught. At first glance it looks like this is to ensure that runtime.terminate() gets called, but in fact it doesn't, the catch block doesn't do it and there is no scope(exit).  Is this a problem? (And what would happen if you didn't catch the exception?)
2. Why does the boilerplate return 0 on success and failure? (If the return code is irrelevant, why the comment that says "failed" next to the return code?)
3. I can't imagine a technical reason why the myWinMain signature has to match the WinMain signature. Wouldn't it be better to omit the hPrevInstance since it isn't used? (Or are we preserving backwards compatibility with Win16?).

If there is a resource somewhere that explains all this I would happy to consult it but I couldn't find anything.

Thanks.
June 29, 2014
On 2014-06-29 06:47, Jeremy Sorensen wrote:
> I found an example of boilerplate code for Win32 programming in D here:
> http://wiki.dlang.org/D_for_Win32
>
> I have some questions.
> 1. It appears that the call to myWinMain from WinMain is to ensure that
> any exception or error is caught. At first glance it looks like this is
> to ensure that runtime.terminate() gets called, but in fact it doesn't,
> the catch block doesn't do it and there is no scope(exit).  Is this a
> problem? (And what would happen if you didn't catch the exception?)
> 2. Why does the boilerplate return 0 on success and failure? (If the
> return code is irrelevant, why the comment that says "failed" next to
> the return code?)
> 3. I can't imagine a technical reason why the myWinMain signature has to
> match the WinMain signature. Wouldn't it be better to omit the
> hPrevInstance since it isn't used? (Or are we preserving backwards
> compatibility with Win16?).
>
> If there is a resource somewhere that explains all this I would happy to
> consult it but I couldn't find anything.

You don't need to use WinMain. You can use a plain D main function and add the "-L/SUBSYSTEM:WINDOWS:4.0" link flag to suppress the console. There are API's to get access to the arguments passed to WinMain, if necessary.

-- 
/Jacob Carlborg
June 29, 2014
On Sunday, 29 June 2014 at 07:51:50 UTC, Jacob Carlborg wrote:
>
> You don't need to use WinMain. You can use a plain D main function and add the "-L/SUBSYSTEM:WINDOWS:4.0" link flag to suppress the console. There are API's to get access to the arguments passed to WinMain, if necessary.

OK so I just tried this and found some amazing things.  By using main instead of WinMain the std runtime is automatically loaded, and uncaught exceptions are not swallowed up like in WinMain, so you don't need the try-catch anymore!  This makes life much better.  The only question I have is what happens when you use SUBSYSTEM:WINDOWS:4.0 (Which I understand means XP or higher) and the program runs on something older? Will you get an error message or just silent failure?

June 29, 2014
> The only question I have is what happens when you use SUBSYSTEM:WINDOWS:4.0 (Which I understand means XP or higher) and the program runs on something older?

<WinXP is dead :)
June 29, 2014
On 2014-06-29 17:06, Jeremy Sorensen wrote:

> The only question I
> have is what happens when you use SUBSYSTEM:WINDOWS:4.0 (Which I
> understand means XP or higher) and the program runs on something older?
> Will you get an error message or just silent failure?

Actually, I don't know. You could try some different value. If you search on Google I'm sure you'll find something.

-- 
/Jacob Carlborg
June 30, 2014
On Sunday, 29 June 2014 at 18:16:05 UTC, Jacob Carlborg wrote:
> On 2014-06-29 17:06, Jeremy Sorensen wrote:
>
>> The only question I
>> have is what happens when you use SUBSYSTEM:WINDOWS:4.0 (Which I
>> understand means XP or higher) and the program runs on something older?
>> Will you get an error message or just silent failure?
>
> Actually, I don't know. You could try some different value. If you search on Google I'm sure you'll find something.

Good suggestion, it took me a bit to figure out how to convince Visual-D to do it, but I got it.  I am using windows 8.1, so I had to use an as-yet fictitious number but when I did Windows told me it couldn't run the program, which is just perfect behavior.

June 30, 2014
On Sunday, 29 June 2014 at 07:51:50 UTC, Jacob Carlborg wrote:

> You don't need to use WinMain. You can use a plain D main function and add the "-L/SUBSYSTEM:WINDOWS:4.0" link flag to suppress the console. There are API's to get access to the arguments passed to WinMain, if necessary.

Thanks for your help on this, I couldn't find a way to get the nCmdShow argument, is it safe to assume SW_SHOWNORMAL for starting a new application?

So the situation so far is this:
1. You don't need hPrevInstance
2. You can get hInstance via GetModuleHandle(null) (I think that is the best way)
3. [awesome] use main(string[] args) to get your command line arguments exactly like you are used to (except no program name, I tested this)
4. You don't have to worry about the runtime, it is handled automatically
5. You don't have to catch at the top level and put up a message box, this is also done automatically

Assuming the nCmdShow thing isn't a problem I see no reason why the wiki should tell people to use WinMain at all.

June 30, 2014
On Monday, 30 June 2014 at 05:30:23 UTC, Jeremy Sorensen wrote:
> Assuming the nCmdShow thing isn't a problem I see no reason why the wiki should tell people to use WinMain at all.
If MSDN is to be believed
VOID WINAPI GetStartupInfo(
  _Out_  LPSTARTUPINFO lpStartupInfo
);
will get you nCmdShow and lots of other goodies.
June 30, 2014
> If MSDN is to be believed
> VOID WINAPI GetStartupInfo(
>   _Out_  LPSTARTUPINFO lpStartupInfo
> );
> will get you nCmdShow and lots of other goodies.

I keep getting "Error: undefined identifier GetStartupInfo" (or GetStartupInfoA, or GetStartupInfoW).  According to MSDN it should be available from <Windows.h>, which according to the D documentation means "import core.sys.windows.windwos" should make it available.  I still don't know the right way to pass a pointer to it, but I don't think that is causing this error.  Any ideas?
Thanks.

June 30, 2014
On Monday, 30 June 2014 at 15:14:24 UTC, Jeremy Sorensen wrote:
> documentation means "import core.sys.windows.windwos"

The Windows headers that come with D are pathetically minimal. You'll need to grab a more complete win32 header OR copy/paste the individual prototypes off MSDN and use them that way.

So add this to your D file after importing core.sys.windows.windows:

extern(Windows)
void GetStartupInfoA(STARTUPINFO*); // the pathetic druntime Windows headers define TCHAR as ascii, so we'll use the A version


And try compiling it. If it complains that STARTUPINFO is undefined too, copy its prototype in:

struct STARTUPINFO {
  DWORD  cb;
  LPTSTR lpReserved;
  LPTSTR lpDesktop;
  LPTSTR lpTitle;
  DWORD  dwX;
  DWORD  dwY;
  DWORD  dwXSize;
  DWORD  dwYSize;
  DWORD  dwXCountChars;
  DWORD  dwYCountChars;
  DWORD  dwFillAttribute;
  DWORD  dwFlags;
  WORD   wShowWindow;
  WORD   cbReserved2;
  LPBYTE lpReserved2;
  HANDLE hStdInput;
  HANDLE hStdOutput;
  HANDLE hStdError;
}


And that should make it work.
« First   ‹ Prev
1 2