Window Icon

What it says on the tin: a place to discuss proposed new features.
User avatar
CaseyB
OGRE Contributor
OGRE Contributor
Posts: 1335
Joined: Sun Nov 20, 2005 2:42 pm
Location: Columbus, Ohio
x 3
Contact:

Window Icon

Post by CaseyB »

I know this wouldn't be a high priority as most Ogre apps are run in fullscreen mode anyway, but would it be possible to add something to the platform managers to allow you to change the default window icon in a cross-platform manner?
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

If you really need that feature, keep in mind that it is easy to tell Ogre to render in your own custom window.
User avatar
CaseyB
OGRE Contributor
OGRE Contributor
Posts: 1335
Joined: Sun Nov 20, 2005 2:42 pm
Location: Columbus, Ohio
x 3
Contact:

Post by CaseyB »

I don't really need it, I just thought that it might be a nice thing to have, again, to maintain cross-platformability.
PatrickB3
Greenskin
Posts: 101
Joined: Mon May 09, 2005 3:37 am
Location: California, USA

Post by PatrickB3 »

It not as much as need as really really want. The only change I ever make to the Ogre code is for the icon. Yeah you can make your own window but why bother when all you want is to change the icon. So every new release of Ogre I go and change the icon again.

It's not life or death but it would be really nice to just pass in the icon wanted since we already can with the window name.
klauss
Hobgoblin
Posts: 559
Joined: Wed Oct 19, 2005 4:57 pm
Location: LS87, Buenos Aires, República Argentina.

Post by klauss »

It has its complications if you want crossplatformability.
Like... what format? png? Good luck in windows ;)

It's not trivial enough, but ya... would be nice.
If anyone has time to spare :D
Oíd mortales, el grito sagrado...
Hey! What is it with that that?
Wing Commander Universe
pkdawson
Kobold
Posts: 25
Joined: Thu Mar 16, 2006 10:12 pm
Location: Noo Yawk

Post by pkdawson »

klauss wrote:It has its complications if you want crossplatformability.
Like... what format? png? Good luck in windows ;)
That's not really an issue. OGRE already depends on DevIL, which supports all sorts of conversions.
morricone
Gnoblar
Posts: 24
Joined: Tue Mar 15, 2005 8:03 pm

Post by morricone »

pkdawson wrote:
klauss wrote:It has its complications if you want crossplatformability.
Like... what format? png? Good luck in windows ;)
That's not really an issue. OGRE already depends on DevIL, which supports all sorts of conversions.
Actually it is an issue, because you need the .ico format and DevIL (which is deprecated, btw) can't save to .ico.
User avatar
pjcast
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2543
Joined: Fri Oct 24, 2003 2:53 am
Location: San Diego, Ca
x 2
Contact:

Post by pjcast »

In anycase, Ogre is a rendering engine. While it has some support for creating windows (for the most common settings), it is not supposed to handle all issues of creating a window, icons, dialogs, etc etc.

If you really need this, it is simple to modify Ogre to use your custom Icon. That way, you don't have to include any OS dependent code in your own app. Though, it is not that hard to create some windowing code in your own app that can create and decorate your own window (using #ifdef's for different platforms). And, that is your choice. I doubt Ogre will ever be all encompassing for window creation.
Have a question about Input? Video? WGE? Come on over... http://www.wreckedgames.com/forum/
PatrickB3
Greenskin
Posts: 101
Joined: Mon May 09, 2005 3:37 am
Location: California, USA

Post by PatrickB3 »

Regardless of should, could, or can it would make life easier. It really isn't neccessary for it to even know what type of file it is. It could be defined in a configuration file or passed in without an extension where the proper extension is added depending on the platform and if you want it, you have to include the correct ones.

Though no one ever wants to say it, Windows is the platform most care about. Cross-platform would be nice but it's not like the icon is the biggest concern when porting. Sure Ogre is cross platform but very little if any of the rest of the code will be anyways.

I could live if I had to if both Mac users and the one Linux user that purchases my game doesn't even get an icon. To be honest I don't even include the OpenGL plug-in. Testing everything twice is too much for my needs. On a large game this is really expensive and though Ogre works on both DirectX and OpenGL I have found my code often does not.

That said, I will continue rebuilding with the icon I want. I just thought if I had to do it maybe others would like it as a feature too.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3
Contact:

Post by SpaceDude »

Sorry for digging up an old thread but I stumbled across this while I was searching how to set my icon in Ogre. I think I can live without an icon for my game but it would be a nice feature. wxWidgets has a neat system for supporting icons across different platforms, so if it was to be implemented it would be worth having a look at their documentation:

http://www.wxwidgets.org/manuals/stable ... rview.html
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

Then use WxWidgets - if your application runs in windowed mode.
Otherwise: Don't bother. The user cannot see a window icon in fullscreen mode.. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3
Contact:

Post by SpaceDude »

jacmoe wrote:Then use WxWidgets - if your application runs in windowed mode.
Otherwise: Don't bother. The user cannot see a window icon in fullscreen mode.. :wink:
There are a few cases when the user will see the icon even in fullscreen mode (i.e. when the user presses ALT+TAB to get back to windows, the icon is visible in the Taskbar as well as the ALT+TAB list).

I also plan to leave the user the option to run in windowed mode, I mainly use this mode myself for debugging.

I realize this isn't a top priority, just something nice to have to make Ogre even better than it is already if it isn't too much trouble to implement.
Hollowtip
Gnoblar
Posts: 2
Joined: Sun Jun 24, 2007 5:30 pm

Post by Hollowtip »

After 1/2 hour of searching MSDN and testing code, I came up with this (I was searching the forums to solve this same problem)

Code: Select all

// Here we choose to let the system create a default rendering window by passing 'true'
mWindow = mRoot->initialise(true, APPLICATION_NAME);

//Lets load a custom icon into the window class
HWND hwnd = 0;
mWindow->getCustomAttribute("HWND", (void*)&hwnd);
if(hwnd != 0)
{
	LONG iconID	= (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APP_ICON) );
	SetClassLong( hwnd, GCL_HICON, iconID );
}
else
{
	throw "Failed to get the handle to the created window, check ogre version!";
}

I'll do a quick walkthrough of exactly how this code works for those just picking up Ogre (like me), or have little experience with MSVC++ resources.

First we have Ogre's standard window creation method.

Code: Select all

mWindow = mRoot->initialise(true, APPLICATION_NAME);
Note that I have macro'd the name that will show in the title bar.

Next we grab the HWND of the window created by Ogre (I found this when I was setting up DXInput, need gamepads).

Code: Select all

mWindow->getCustomAttribute("HWND", (void*)&hwnd);
Please note that in my short experience, I've found that the name for the custom attribute for the "HWND" changes (one version it was "WINDOW" i believe).

Now its time to load the icon from the resource file (which is convienently stored within the .exe itself)

Code: Select all

	LONG iconID	= (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APP_ICON) );
Now there are a few things happening here that may not be common knowledge for those who don't deal with windows code often.

First we have the 'GetModuleHandle' call, this returns a pointer to the module specified via a string, but when a NULL (i.e. 0) pointer is passed in, it returns the current module (NOTE: because of this, this code must be in the same file as the resource, i.e. if the code is in a DLL, put the icon resource in the DLL). This is simply to tell the 'LoadIcon' call where to find the resource.

Next we specify the resource ID. When you create a resource in Visual Studio, it is assigned an ID, this can be changed (as I have done) and is then stored in a header file (usually "resource.h"). This value is then translated by the macro call 'MAKEINTRESOURCE', so it can be properly understood by the 'LoadIcon' call (which usually takes a string).

Then 'LoadIcon' uses this data to load the icon, but returns a handle. This handle isn't good as is (will at least cause a warning, if not an error) because 'SetClassLong' only takes a long value, so we'll type cast it here.

Now that we've got all the data we need, its time to actually tell the window to use this icon as its own.

Code: Select all

SetClassLong( hwnd, GCL_HICON, iconID );
This should be fairly easy to understand now. We simply tell windows to set the 'GCL_HICON' (HICON being a handle to an icon, glc being the global class definintion) value in the window specified by 'hwnd' (which we grabbed from ogre) to the icon that we just loaded.

Although this is currently setup to load the icon from a resource, there are some other loadicon functions that can load it directly from a file. The cool thing about doing it this way is that it also sets the icon for the file that will be seen in Windows Explorer, and any shortcut icons linked to the file (not quite sure what happens if u have multiple icon resources though).

Anyways, if you need anymore help, just post, and I'll hopefully reply.

P.S. sorry for the lengthy 'quick' walkthrough
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

It would be easier to add this in RenderSystems\Direct3D9\src\OgreD3D9RenderWindow.cpp, line 234.
And in RenderSystems\GL\src\OgreWin32Window.cpp, line 219.

I believe you can just paste this in:

Code: Select all

LONG iconID   = (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(101) );
SetClassLong( mHWnd, GCL_HICON, iconID );
I chose the value '101' because Ogre is not able to know what resource script you've got.
So make sure that your icon define is set to that value.

It works! :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

It works for both OpenGL and D3D9.

Can someone please test this and send in a patch?

My CVS is dirty at the moment, and it will take me too long to clean it up to make a proper patch.

Let's hope that this puts an end to the constant whining about this feature not being there. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

OK. The patch is up:
http://sourceforge.net/tracker/index.ph ... tid=302997

Try this at home. :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3
Contact:

Post by SpaceDude »

Good stuff guys... Just tried your patch jacmoe, it works! But I found simpler solution which has the same effect:

Changing:

Code: Select all

			WNDCLASS wc = { 0, WindowEventUtilities::_WndProc, 0, 0, hInst,
				LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "OgreD3D9Wnd" };
To:

Code: Select all

			WNDCLASS wc = { 0, WindowEventUtilities::_WndProc, 0, 0, hInst,
				LoadIcon(GetModuleHandle(0), IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "OgreD3D9Wnd" };
in RenderSystems\Direct3D9\src\OgreD3D9RenderWindow.cpp line 224
Similarly in RenderSystems\GL\src\OgreWin32Window.cpp line 211

Although these patches only apply the icon to the application in the taskbar. The icon at the top left of the window remains unchanged. I'm sure this can be changed too fairly easily, I will report back if I found a solution.
Hollowtip
Gnoblar
Posts: 2
Joined: Sun Jun 24, 2007 5:30 pm

Post by Hollowtip »

Those solutions are great, but if you are a novice (or don't feel like editing ogre, dowloading the required libraries and rebuilding it) then my solution would probably be best.

But if ogre doesn't scare you, and you don't mind spending more than 30 seconds in compile time, then go ahead and use SpaceDude's solution (which is pretty much THE standard specified by MSDN). Though i'd be dubious of weather the dll needs to contain the icon or the exe (could u clear this up SpaceDude, thx).

Also, there is the problem of resource ID's (as jacmoe pointed out), so you just have to make sure to have a 'reserved' ID that is always an icon (its possible to actually tell it to load a string, window panel or other resource as an Icon, but since i've never actually done this, i have no idea if it would crash, give corrupt data or just ignore the call).
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3
Contact:

Post by SpaceDude »

Hollowtip wrote:Though i'd be dubious of weather the dll needs to contain the icon or the exe (could u clear this up SpaceDude, thx).
Somehow it just works. I didn't embed my icon inside the ogre .dll or anything. All I did was modify that one line of code. And the Icon I have already set up for viewing in Windows Explorer just appeared. So there is no need to edit the ogre source code at all if this patch is taken into ogre.
Hollowtip wrote:Also, there is the problem of resource ID's (as jacmoe pointed out), so you just have to make sure to have a 'reserved' ID that is always an icon (its possible to actually tell it to load a string, window panel or other resource as an Icon, but since i've never actually done this, i have no idea if it would crash, give corrupt data or just ignore the call).
Again, I'm a little mystified about jacmoe's magic number of 101, It doesn't seem to matter what this number is. If you replace MAKEINTRESOURCE(101) with IDI_APPLICATION it also works. Where APPLICATION is just a macro defined as:

Code: Select all

#define IDI_APPLICATION     MAKEINTRESOURCE(32512)
in "winuser.h"

I think its probably best to use that, I don't like using magic numbers unless they are hidden from me by a macro :D

But there is still the issue that the icon does not appear at the top left when in windowed mode. What about your technique Hollowtip, does the icon appear or not? I didn't try it yet.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

It doesn't work if using IDI_APPLICATION, I've tried that.
I chose the number 101 because that is the number the MS app wizards tends to use for the application icon (IDI_ICON).
And I chose to use a number instead of a define, because I don't want the rendersystems to know about any resource scripts.
It's all resolved at runtime.
If you recompile the rendersystems, you don't have to relink anything: it's all there. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

SpaceDude: Your solution forces the user to define their icon as 32512 !
I think 101 is a lot simpler.

But I like your solution. File a patch. :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3
Contact:

Post by SpaceDude »

jacmoe wrote:SpaceDude: Your solution forces the user to define their icon as 32512 !
I think 101 is a lot simpler.
Ok I get it, sorry I don't use resource files much. I defined a resource as 102 (I think it got auto-generated at some point), which is why the icon wasn't showing at the top left of the window (*I think*, I need to test this when I get home). But I don't think its a good idea to hard-code that number in. Perhaps the resource number should be passed in as an argument to Ogre::Root::initialise. Something like this:

Code: Select all

RenderWindow* Ogre::Root::initialise(bool autoCreateWindow, const String &windowTitle = "OGRE Render Window", int iconResourceID = 101)
Although that is rather windows specific... hmmm. In the mean time I will go with Hollowtip's method since it doesn't require modifying ogre. Its just a pain having to keep a modified version of ogre for every time i want to compile on a different computer.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3
Contact:

Post by SpaceDude »

Quick update, I now have the icon display at the top left of the window. It was because the resource ID didn't match properly. It seems though that even if they don't match the icon in the taskbar will still be displayed.

I'm using Hollowtip's method now. Works great! Thanks for that.
Hollowtip wrote: Please note that in my short experience, I've found that the name for the custom attribute for the "HWND" changes (one version it was "WINDOW" i believe).
Yes, I'm using ogre 1.4.2, and the window name seems to be "WINDOW" instead of "HWND".
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Post by jacmoe »

Sinbad rejected the patch - and I am glad he did!

You know, all it takes is six lines of code:

Code: Select all

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
HWND hwnd;
mWindow->getCustomAttribute("WINDOW", (void*)&hwnd);
LONG iconID   = (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(IDI_WHATEVAR) );
SetClassLong( hwnd, GCL_HICON, iconID );
#endif
:)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3
Contact:

Post by SpaceDude »

jacmoe wrote:You know, all it takes is six lines of code
Yeah, that's what Hollowtip has been saying all along :oops:
Post Reply