March 01, 2011
== Quote from Denis Koroskin (2korden@gmail.com)'s article
> On Tue, 01 Mar 2011 02:08:48 +0300, Tyro[a.c.edwards]
<nospam@home.com>
> wrote:
> > == Quote from Denis Koroskin (2korden@gmail.com)'s article
> >> On Mon, 28 Feb 2011 19:35:47 +0300, Tyro[a.c.edwards]
> > <nospam@home.com>
> >> wrote:
> >> > On 2/28/2011 11:08 PM, J Chapman wrote:
> >> >> == Quote from Tyro[a.c.edwards] (nospam@home.com)'s article
> >> >>> Both implementations results in error code 1812 being
> > returned from
> >> >>> GetLastError. explanation of the code reads:
> >> >>>        ERROR_RESOURCE_DATA_NOT_FOUND
> >> >>>        1812 (0x714)
> >> >>>        The specified image file did not contain a resource
> > section.
> >> >>> The code I'm porting initially consisted of a resource.h
> > file, a
> >> >>> generic.rc file and two icons. I have not tried to include
> > the icons
> >> >>> and
> >> >>> generic.rc file in the compilation because I do not know
how
> > to as yet
> >> >>> and I've only used half of the resource.h file: didn't
think
> > I need the
> >> >>> whole thing. Could this be the reason for the error? If so
> > could you
> >> >>> direct me to the explanation of how to prepare these files
> > for
> >> >>> inclusion
> >> >>> in the compilation process?
> >> >>> Thanks,
> >> >>> Andrew
> >> >>
> >> >> You need to compile the .rc file (see
> >> >> http://www.digitalmars.com/ctg/rcc.html), then add the
> > resulting .res
> >> >> file
> >> >> to dmd's command line.
> >> >
> >> > Awesome, this does the trick. However I get get a "GP
Fault"?
> > during
> >> > execution. Using windbg, I tracked it down to this piece of
> > code:
> >> >
> >> > void Create()
> >> > {
> >> >    _hwnd = CreateWindowExA(
> >> >      _exStyle,
> >> >      cast(const(char*))_wc.GetName(), // returns string
> >> >      cast(const(char*))_windowName,   // string variable
> >> >      _style,
> >> >      _x,
> >> >      _y,
> >> >      _width,
> >> >      _height,
> >> >      _hWndParent,
> >> >      _hMenu,
> >> >      _wc.GetInstance(),
> >> >      _data);
> >> >
> >> >      assert(_hwnd, "Internal error: Window Creation
Failed.");
> >> > }
> >> >
> >> > The program craps at assert() but the error is generated. It
> > just
> >> > displays a dialog box with the message: "test.exe has
stopped
> > working,
> >> > Windows is checking for a solution to the problem..."
> >> >
> >> > I'm thinking that _hwnd was never initialized and that
assert
> > is access
> >> > a null pointer but I cannot be sure. Any suggestions or
ideas?
> >> The
> >> >  cast(const(char*))_wc.GetName()
> >> line look *very* suspicious. You can't get a string and just
> > cast it to
> >> const(char)*. Most importantly, the string (most likely) is
not
> >> null-terminated.
> >> What you need to do here is the following:
> >> auto className = toStringz(_ws.GetName());
> >> auto caption = toStringz(_windowName);
> >> and pass those 2 to the function.
> >
> > Actually I've already tried that, it has no effect on the
outcome.
> > From your suggestion though, I've gone back and replace all the
> > cast(const(char*)) usage throughout the program. Final verdict:
> > the program still crashes it the same location. It actually
never
> > returns from CreateWindowExA().
> >
> >> Alternatively, you could make sure your strings are null-
> > terminated and
> >> pass the pointer directly (e.g. _windowName.ptr):
> >> string _windowName = "foo"; // null-terminated automatically
> >> string _caption = ("Hello, World" ~ "\0")[0..$-1]; // append
> > trailing zero
> >> to an existing string but exclude it from result (so that it's
> > not
> >> included in _caption.length)
> >
> This is indeed strange, but it has nothing to do with the
function itself.
> I still think the parameters you are passing might be invalid.
Try setting
> them to default values and see if that helps. Also try wrapping
the call
> with a try/catch block and output an exception you are getting
(if any).


The problem occurs at the site of the assertion. I wrapped the function in a try/catch block and placed a call to MessageBoxA() on either end of the the try block. Both calls to MessageBox fires and the appropriate messages displayed. No exception is thrown: made evident my the fact that the third call to MessageBox, embeded in catch{}, is not fired. Nevertheless, execution haults at the very next line following/catch and Create() never returns.
March 01, 2011
On 3/1/2011 12:25 AM, Tyro[a.c.edwards] wrote:
>  Nevertheless, execution haults
> at the very next line following/catch and Create() never returns.

CreateWindow sends a few messages to your window proc; anything interesting happening there?
March 01, 2011
On 3/1/2011 7:18 PM, Bekenn wrote:
> On 3/1/2011 12:25 AM, Tyro[a.c.edwards] wrote:
>> Nevertheless, execution haults
>> at the very next line following/catch and Create() never returns.
>
> CreateWindow sends a few messages to your window proc; anything
> interesting happening there?

Not sure how to check those messages, but I guess that's a cue for me to do some more research. Off to Google land I go...
March 03, 2011
On 3/1/2011 8:25 PM, Tyro[a.c.edwards] wrote:
> On 3/1/2011 7:18 PM, Bekenn wrote:
>> On 3/1/2011 12:25 AM, Tyro[a.c.edwards] wrote:
>>> Nevertheless, execution haults
>>> at the very next line following/catch and Create() never returns.
>>
>> CreateWindow sends a few messages to your window proc; anything interesting happening there?
>
> Not sure how to check those messages, but I guess that's a cue for me to do some more research. Off to Google land I go...

After much searching, I've finally located the actual cause of the problem:

class TopWinClass: WinClass
{
	this(ushort resId, HINSTANCE hInst, WNDPROC wndProc)
	{
		super(resId, hInst, wndProc);
		SetResIcons(resId);
		wc.lpszMenuName = MAKEINTRESOURCEA(resId);  // [PROBLEM]
	}
}

The root cause of the problem begins with a lack of understanding of how to create a proper resource file for D. I simply took the C++ version, compiled it with rcc and linked it to my project: No changes whatsoever. Turn out that made the compiler/linker stop complaining, however MAKEINTRESOURCEA(resId) still cannot locate the correct resources or cannot properly use the resource it finds to initialize wc.lpszMenuName. Every access to wc.lpszMenuName after this point fails. If initialize wc.lpszMenuName with one of the default strings, say "STATIC" at this point, the program runs to completion. I've attached the resource file, it hopes that someone could help me with it's conversion.

Thanks.


March 04, 2011
Tyro[a.c.edwards] Wrote:

> class TopWinClass: WinClass
> {
> 	this(ushort resId, HINSTANCE hInst, WNDPROC wndProc)
> 	{
> 		super(resId, hInst, wndProc);
> 		SetResIcons(resId);
> 		wc.lpszMenuName = MAKEINTRESOURCEA(resId);  // [PROBLEM]
> 	}
> }
> 
> Every access to wc.lpszMenuName after this point fails.

Who accesses it?

MAKEINTRESOURCEA just casts int to char* so it's an invalid pointer while still valid resource indentifier, windows can differentiate them by zeroed high word.
March 04, 2011
Kagamin Wrote:

> Tyro[a.c.edwards] Wrote:
> 
> > class TopWinClass: WinClass
> > {
> > 	this(ushort resId, HINSTANCE hInst, WNDPROC wndProc)
> > 	{
> > 		super(resId, hInst, wndProc);
> > 		SetResIcons(resId);
> > 		wc.lpszMenuName = MAKEINTRESOURCEA(resId);  // [PROBLEM]
> > 	}
> > }
> > 
> > Every access to wc.lpszMenuName after this point fails.
> 
> Who accesses it?
> 
> MAKEINTRESOURCEA just casts int to char* so it's an invalid pointer while still valid resource indentifier, windows can differentiate them by zeroed high word.

casts ushort to char*
1 2
Next ›   Last »