tags:

views:

58

answers:

2

I have created a basic application with with windows api. It just displays a small window. I am starting from main function, getting the instance, created my windows class, etc. Everything works out fine. The problem I have however is that my custom icon will not display in the top left corner of the window or on the task bar, it just shows the default little picture of a window. It does however show up as the icon for my the actual click-able exe file. I used resedit to make my resources, and created all 4 icon sizes so it should have one available of the proper size. I got the handle with

HICON hMyIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));

I then used WNDCLASSEX and gave the handle to both hIcon and hIconsm. If there is anything that could cause it to not show up in the corner or task bar, please help.

#include <Windows.h>
#include <iostream>
#include "resource.h"
//globals
    MSG msg;
    HWND hwndwnd;
    HICON hMyIcon;
//Windows Procedure
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
    switch ( message )
    {
    case WM_CLOSE:    
        exit( 0 );
        break;    
    case WM_CREATE:
        SendMessage(hwndwnd,WM_SETICON,ICON_SMALL,(LPARAM)hMyIcon);
        break;
    }
    return DefWindowProc( hwnd, message, wparam, lparam );
}

int main(int ArgumentNum, char *arg[])
{
    //get instance
    char title[500];
    GetConsoleTitleA( title, 500 );
    HWND hwndConsole = FindWindowA( NULL, title );
    HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hwndConsole, GWLP_HINSTANCE);
    //get icon handle
    hMyIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    if (hMyIcon == NULL)
    {
         std::cout<< "NULL\n";
    }
    //create & register class
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_DROPSHADOW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = hMyIcon;
    wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wc.lpszMenuName = 0;
    wc.lpszClassName = "Jacob";
    wc.hIconSm = hMyIcon;
    RegisterClassEx(&wc);
    //create window
    hwndwnd = CreateWindow("Jacob", "My Window", 
    WS_OVERLAPPEDWINDOW, 520, 20, 300, 300, NULL, NULL, hInstance, NULL);
    //Tried sendmessage here as well
    //SendMessage(hwndwnd,WM_SETICON,ICON_SMALL,(LPARAM)hMyIcon);
    ShowWindow( hwndwnd, SW_SHOWNORMAL);
    UpdateWindow( hwndwnd );
    //hide console, not using to see if icon is null
    //ShowWindow( hwndConsole, 0 );
    //message loop
    while(GetMessage( &msg, hwndwnd, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

This is my source code. What im starting to wonder is if my problem has anything to do with my resources. When i used resedit i mad an icon of every possible size. Hope this Helps, and thanks for the patience.

+2  A: 
  • Are you sure your LoadIcon calls return != NULL?
  • LoadIcon always loads a 32x32 icon, MSDN says if hIconSm is NULL, it checks the icon resource for a icon with the correct size so maybe you should try to set hIconSm=NULL;
  • You could use WM_SETICON

Edit:

//(Having your code from the start would have made things easier)
#include <Windows.h>
#include "resource.h"
MSG msg;
HWND hwndwnd;
HICON hMyIcon;

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
    switch ( message )
    {
    case WM_CLOSE:    
        DestroyWindow(hwnd);//exit( 0 );
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_CREATE:
//        SendMessage(hwndwnd,WM_SETICON,ICON_SMALL,(LPARAM)hMyIcon);
        break;
    }
    return DefWindowProc( hwnd, message, wparam, lparam );
}


int main(int ArgumentNum, char *arg[]) 
{
/*
    You don't own/control the console window, don't use it's HWND if you don't have to.
    ...And there is even a function to get the HWND if you need it, no need for FindWindow

    char title[500];
    GetConsoleTitleA( title, 500 );
    HWND hwndConsole = FindWindowA( NULL, title );
    HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hwndConsole, GWLP_HINSTANCE);
    */
    HINSTANCE hInstance=GetModuleHandle(NULL);
    hMyIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_DROPSHADOW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = hMyIcon;
    wc.hCursor = LoadCursor(/*hInstance*/NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wc.lpszMenuName = 0;
    wc.lpszClassName = "Jacob";
#if 1 //The easy way
    wc.hIconSm = NULL;//hMyIcon; LoadIcon only loads 32x32 icons, you would get the wrong icon
#else //The hard way
    wc.hIconSm = (HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
#endif
    RegisterClassEx(&wc);
    //create window
    hwndwnd = CreateWindow("Jacob", "My Window", 
    WS_OVERLAPPEDWINDOW, 520 , 20, 300, 300, NULL, NULL, hInstance, NULL);
    ShowWindow(hwndwnd,SW_SHOW);
    while(GetMessage( &msg, /*hwndwnd*/NULL, 0, 0) >0 ) //normally not a good idea to specify a hwnd
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
Anders
I have determined it does not return NULL with if (hMyIcon == NULL) { std::cout << "NULL\N" ; }. I also tried it with setting hIconSm to NULL in my class i was registering. But how do i go about using WM_SETICON. im not so good with using messages yet.
JAKE6459
After CreateWindow, do SendMessage(yourwindow,WM_SETICON,ICON_SMALL,(LPARAM)youriconhandle); (You can also set the large icon this way)
Anders
i tried that as well. could it have anything to do with me not using the winmain function, because im registering my class and creating my window in just the main function, so do i need winmain for it to work? would you like me to edit my post and put my source in?
JAKE6459
No, you don't need WinMain, but you do need a message loop. Posting your code would probably help
w0lo
Source posted, hopefully i formatted it right when i did.
JAKE6459
Got it, thanks for all the help guys, greatly appreciated. Now time to start reading my new book, "game engine architecture".
JAKE6459
+1  A: 

My first suggestion would be to try loading a standard icon instead of your own icon:

hMyIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ERROR));

This should probably work, and you should see the red error message icon.

The next thing to do is try to obtain the instance handle in a different way. Console windows are a strange breed, don't mix them too much with the rest of the Win32 API. Try:

hInstance = GetModuleHandle(NULL);
casablanca
WOOOOOO, it works, how is the instance returned from the GetModuleHandle function different from the one returned from the method i used?
JAKE6459
I'll post a modified version of your source, see my comments...
Anders
@Jake: Because console windows are quite different from normal windows. The "window" itself resides in a separate system process (CSRSS) and trying to use standard API functions on it won't get you expected results. Read [this article](http://blogs.msdn.com/b/oldnewthing/archive/2007/12/31/6909007.aspx) for a bit of related history.
casablanca