- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Hi there, I have a simple question:
Assuming that I already have an .ICO file, how do I change the program icon for a console application?
링크가 복사됨
26 응답
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Assuming your .ico is included in a compiled .res, you use the LoadImage API to switch .ico's at run time and then call PostMessage.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Well, I don't have the .RES file, I simply have the .ICO file I made with an icon creator program, but I'll manage it.
Thank you for your reply!
Thank you for your reply!
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I'm using IVF 11.1 with the Visual Studio 2008 shell that come with the compiler and cannot figure how to assign an icon to my console application. If anyone knows how to do it in this environment, I would greatly appreciate them telling us how.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Apparently there is an Windows API called SetConsoleIcon (hIcon) in Kernel32.dll.
To use it you need to
Create a resource file containing your icon and compile it with your console program.
Get the handle to executable module that is running the console e.g.
hModule=GetModuleHandle(0)
Load the icon resource using the module handle and the icon's ID, saving its handle e.g.
load the Kernel32.dll library and save its handle e.g.
Use GetProcAddress on the handle to the library to get a pointer to SetConsoleIcon
Use the pointer to call SetConsoleIcon function with the icon's handle as the argument.
Release the library using FreeLibrary
You will need to write a simple interface block for SetConsoleIcon. Just find an interface block for a Windows API function that takes one integer argument and edit it to suit.
To use it you need to
Create a resource file containing your icon and compile it with your console program.
Get the handle to executable module that is running the console e.g.
hModule=GetModuleHandle(0)
Load the icon resource using the module handle and the icon's ID, saving its handle e.g.
hMainIcon = LoadIcon( hModule, MAKEINTRESOURCE( IDI_ICON3 ))
load the Kernel32.dll library and save its handle e.g.
hLibrary = LoadLibrary(
"Kernel32.dll"
C)
Use GetProcAddress on the handle to the library to get a pointer to SetConsoleIcon
Use the pointer to call SetConsoleIcon function with the icon's handle as the argument.
Release the library using FreeLibrary
You will need to write a simple interface block for SetConsoleIcon. Just find an interface block for a Windows API function that takes one integer argument and edit it to suit.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I'll comment that you'll need a resource editor, since Microsoft does not allow us to include it with the VS Shell. You can use ResEdit. Take the files it creates and add them to your project.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Maybe there is aother solution: use the WM_SETICON message (see the SDK), You have to obtain the console handle (callGetConsoleWindow; write your own interface to this routine as the kernell32.for file does not have it) and then you can send a message to that window!
I have no experience with it, but maybe it works!
Robert
I have no experience with it, but maybe it works!
Robert
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I tried the WM_SETICON route using PostMessage and SendMessage and it failed to change the icon. However, the following program works using SetConsoleIcon. Create a Fortran Console Project and add the code and include the attached 32 x 32 icon resource held in Script1.rc
program testconsole
use dfwin
implicit none
INTERFACE
FUNCTION SetConsoleIcon(hIcon)
USE DFWINTY
INTEGER(DWORD) hIcon
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'SetConsoleIcon' :: SetConsoleIcon
END FUNCTION
END INTERFACE
include 'resource.fd'
integer hmodule, hmainicon
integer lret
hModule=GetModuleHandle(0)
hMainIcon = LoadIcon( hModule, MAKEINTRESOURCE( IDI_ICON1 ))
lret=SetConsoleIcon(hMainIcon)
print *, 'Hello World'
pause
end program testconsole
program testconsole
use dfwin
implicit none
INTERFACE
FUNCTION SetConsoleIcon(hIcon)
USE DFWINTY
INTEGER(DWORD) hIcon
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'SetConsoleIcon' :: SetConsoleIcon
END FUNCTION
END INTERFACE
include 'resource.fd'
integer hmodule, hmainicon
integer lret
hModule=GetModuleHandle(0)
hMainIcon = LoadIcon( hModule, MAKEINTRESOURCE( IDI_ICON1 ))
lret=SetConsoleIcon(hMainIcon)
print *, 'Hello World'
pause
end program testconsole
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
My previous post showed code developed using Compaq Visual Fortran. The attached code works using Intel Visual Fortran. I had to change it to use the LoadLibrary/GetProcAddress route because the export library for Kernel32.dll searched by Visual Studio did/does not contain the symbol 'SetConsoleIcon', even though the actual DLL library Kernel32.dll contains the function. I have obtained the pointer to 'SetConsoleTitleA' in the same way and used it. The resource and header files are attached
program changeconsoleicon
use dfwin
! use myinterfaces
implicit none
INTERFACE
FUNCTION SetConsoleIcon(hIcon)
USE DFWINTY
integer(BOOL) :: SetConsoleIcon
INTEGER(DWORD) hIcon
!DEC$ ATTRIBUTES DEFAULT, STDCALL :: SetConsoleIcon
END FUNCTION
END INTERFACE
INTERFACE
FUNCTION ChangeConsoleTitle(lpConsoleTitle)
USE DFWINTY
integer(BOOL) :: ChangeConsoleTitle
!DEC$ ATTRIBUTES DEFAULT, STDCALL :: ChangeConsoleTitle
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpConsoleTitle
character*(*) lpConsoleTitle ! LPCSTR lpConsoleTitle
END FUNCTION
END INTERFACE
include 'resource.fd'
integer hmodule, hMainIcon, hlib
integer lret
! Define Pointers to the required functions
Pointer (SetConsoleF1, SetConsoleIcon)
Pointer (ChangeConsoleF2, ChangeConsoleTitle)
! Load the library and get the addresses of the required functions
hLib = LoadLibrary("KERNEL32.DLL"C)
print *,'Library handle= ',hLib
SetConsoleF1 = GetProcAddress(hLib, 'SetConsoleIcon'C)
print *,'SetConsoleIcon handle= ',SetConsoleF1
ChangeConsoleF2 = GetProcAddress(hLib, 'SetConsoleTitleA'C)
print *,'ChangeConsoleTitle handle= ',ChangeConsoleF2
! Load the icon from the executable module after getting its handle
hModule=GetModuleHandle(0)
hMainIcon = LoadIcon( hModule, MAKEINTRESOURCE( IDI_ICON1 ))
! Change the console Icon and change the title
lret=SetConsoleIcon(hMainIcon)
lret=ChangeConsoleTitle('I have just changed the Console Icon!'c)
print *, 'Hello World'
pause
lret=FreeLibrary(hLib)
end program changeconsoleicon
program changeconsoleicon
use dfwin
! use myinterfaces
implicit none
INTERFACE
FUNCTION SetConsoleIcon(hIcon)
USE DFWINTY
integer(BOOL) :: SetConsoleIcon
INTEGER(DWORD) hIcon
!DEC$ ATTRIBUTES DEFAULT, STDCALL :: SetConsoleIcon
END FUNCTION
END INTERFACE
INTERFACE
FUNCTION ChangeConsoleTitle(lpConsoleTitle)
USE DFWINTY
integer(BOOL) :: ChangeConsoleTitle
!DEC$ ATTRIBUTES DEFAULT, STDCALL :: ChangeConsoleTitle
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpConsoleTitle
character*(*) lpConsoleTitle ! LPCSTR lpConsoleTitle
END FUNCTION
END INTERFACE
include 'resource.fd'
integer hmodule, hMainIcon, hlib
integer lret
! Define Pointers to the required functions
Pointer (SetConsoleF1, SetConsoleIcon)
Pointer (ChangeConsoleF2, ChangeConsoleTitle)
! Load the library and get the addresses of the required functions
hLib = LoadLibrary("KERNEL32.DLL"C)
print *,'Library handle= ',hLib
SetConsoleF1 = GetProcAddress(hLib, 'SetConsoleIcon'C)
print *,'SetConsoleIcon handle= ',SetConsoleF1
ChangeConsoleF2 = GetProcAddress(hLib, 'SetConsoleTitleA'C)
print *,'ChangeConsoleTitle handle= ',ChangeConsoleF2
! Load the icon from the executable module after getting its handle
hModule=GetModuleHandle(0)
hMainIcon = LoadIcon( hModule, MAKEINTRESOURCE( IDI_ICON1 ))
! Change the console Icon and change the title
lret=SetConsoleIcon(hMainIcon)
lret=ChangeConsoleTitle('I have just changed the Console Icon!'c)
print *, 'Hello World'
pause
lret=FreeLibrary(hLib)
end program changeconsoleicon
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
There's no entry for SetConsoleIcon in the MSDN Library list of console functions. This may explain why there is no export symbol for it in kernel32.lib. I can find quite a few examples loading it from the DLL, however. The text I can find suggests that MS never intended this to be used in user applications. The "supported" method is to create a .lnk shortcut for the program and you can set the icon for that.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Your example works well, both as a simple console application and als if added to the source code of my application. Thank you!
I would like to ask if there is any way how to make this work in 64-bit. I get some errors when I try compiling my application for 64-bit systems, namely
- error #6284: There is no matching specific function for this generic function reference. [GETPROCADDRESS]
- error #6284: There is no matching specific function for this generic function reference. [LOADICON]
I just guess this has something to do with the library Kernel32.dll, is that right?
I would like to ask if there is any way how to make this work in 64-bit. I get some errors when I try compiling my application for 64-bit systems, namely
- error #6284: There is no matching specific function for this generic function reference. [GETPROCADDRESS]
- error #6284: There is no matching specific function for this generic function reference. [LOADICON]
I just guess this has something to do with the library Kernel32.dll, is that right?
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Without any experience with 64 bit compilers, taking a quick look I see that the variables hLib and hModule are "regular" 32 bits integers. Under 64-bit programming, handles and pointers must be 64 bits. So, change the definition of these handles to:
INTEGER(KIND=HANDLE) :: hLib, hModule
and I guess it will be go better!
The same applies, basically, to other handles but these seems not to be critical as there are not used in a call to an external winapi function.
Robert
INTEGER(KIND=HANDLE) :: hLib, hModule
and I guess it will be go better!
The same applies, basically, to other handles but these seems not to be critical as there are not used in a call to an external winapi function.
Robert
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Being pleased with a correct functionality of changing the console window icon in one of my applications, I did completely the same is another application and it does not work. This is what I have in the code to change the icon:
[fortran]
use ifwin
interface
function SetConsoleIcon ( hIcon )
use ifwinty
integer(BOOL) :: SetConsoleIcon
integer(DWORD) :: hIcon
!dec$ attributes default, stdcall :: SetConsoleIcon
end function
end interface
integer,parameter :: IDI_ICON_REDOX=101
integer(kind=HANDLE) hModule, hLib
integer hMainIcon, lRet
pointer ( SetConsoleF1, SetConsoleIcon )
hLib = LoadLibrary ( 'Kernel32.dll'C )
SetConsoleF1 = GetProcAddress ( hLib, 'SetConsoleIcon'C )
hModule = GetModuleHandle(0)
hMainIcon = LoadIcon ( hModule, MAKEINTRESOURCE(IDI_ICON_REDOX) )
lRet = SetConsoleIcon ( hMainIcon )
lRet = FreeLibrary ( hLib )
[/fortran]
I have Resources.rc in my Visual Studio project and I checked I have this included in it:
[cpp]
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON_REDOX ICON "icon_RedoxT.ico"
[/cpp]
I also made sure the file icon_RedoxT.ico is in the project directory.
When I debug the code the LoadIcon method returns 0 and I wonder what I'm doing wrong.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Jirina,
I have played with your example and wrote a new one that follows to some extent the one you made. Enclosed is a zip with the Fortran source, the resource script and the icon needed to run the program. I cannot see for what reason your example failed. Hope this helps you!
Robert
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Robert,
I tried the new approach used in the code you've attached and it still did not work in my application. I checked the resource file and realized you have the line [cpp]#define IDI_ICON 101[/cpp] in it, but I did not have anything like that in my resources. After adding this line to resources, everything works like a charm. :-) What puzzles me now is that the icon is successfully set even though I don't have the above mentioned line in resources.
Anyway, thank you very much for your kind help, I appreciate it!
Jirina
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I donwloaded the project, but I am not able to find the source code file ci.f90 referenced in it. Also, the path to the resource file is wrong, but this can be fixed by adding the correct resource file from the project subfolder where I found it.
