The code does this:
- loads the complete icon file into memory
- checks the type. Only BFT_BITMAPARRAY and BFT_COLORICON are interesting.
- scans the bitmap array data looking for an image size to match the
system icon sizes, WinQuerySysValue(HWND_DESKTOP, SV_CXICON).
The "mini" size is set to half the system size.
- GpiCreateBitmap() creates the icon mask and image
- WinCreatePointerIndirect() creates the actual icon
Both regular and mini icon images are created for
WinCreatePointerIndirect(), 4 total.
On my computer WinQuerySysValue() returns the system icon size as 40x40.
The screen size is 1600x1200.
What happens currently is that only the 40x40 (or 32x32 depending on
screen size) size icons are acknowledged; if there are 20x20 or 16x16
versions, those are ignored. WinCreatePointerIndirect() scales the larger
icon down in size to fit the mini-icon format, say 40x40 -> 20x20. That
result is not very appealing since the downsize method deletes every other
row and column to get the 20x20 size.
If I force the use of a 20x20 icon, that image is first scaled up to
40x40 using some dithering to smooth the edges, then scaled down to 20x20,
an even less appealing result.
Is there a better way to do this?
How do I create an mini icon that correctly uses the mini icon images in
the icon file?
Is there documentation that better describes icon manipulation than what
is in the PM Reference?
--
jmm (hyphen) list (at) sohnen-moe (dot) com
(Remove .AXSPAMGN for email)
Did you make sure to pass handles to hbmMinPointer / hbmMiniColor
instead of hbmPointer / hbmColor ?
That should prevent the up-/downscaling that you observe. Don't know
what fPointer does. You should experiment with TRUE/FALSE setting.
Lars
> That should prevent the up-/downscaling that you observe. Don't know
> what fPointer does. You should experiment with TRUE/FALSE setting.
>
From the PM Reference:
"fPointer is set to TRUE if a pointer is being created, or to FALSE if an
icon is being created."
I did try setting the flag to TRUE with even worse results.
> How do I create an mini icon that correctly uses the mini icon images in
> the icon file?
I encountered this problem with RWS, trying to pass WPS mini-icons
to other apps.
WinCreatePointerIndirect() just won't create mini-icons - it ignores
ptrInfo.hbmMiniPointer & ptrInfo.hbmMiniColor. If you put the mini
info in the full-sized fields, it will double each line to create a
misshapen full-sized icon.
However, the resizing process appears to be symmetrical: when you
display one of these bloated icons as a mini, PM will remove every
other line, giving you an exact replica of the original.
If you have RWS installed, you can confirm this using Firefox.
Open a folder in details view, then view the same folder in FF.
Now, use a screen magnifying tool to compare the two. The color
palette may be wrong in FF, but otherwise the two are identical.
--
== == almost usable email address: Rich AT E-vertise.Com == ==
___________________________________________________________________
|
| DragText v3.9 with NLS support
Rich Walsh | A Distinctly Different Desktop Enhancement
Ft Myers, FL | http://e-vertise.com/dragtext/
___________________________________________________________________
> However, the resizing process appears to be symmetrical: when you
> display one of these bloated icons as a mini, PM will remove every
> other line, giving you an exact replica of the original.
>
In this respect I got very lucky when creating the icons for PMMail.
When I made the full size versions, I doubled all of the line widths and
heights from the mini versions. As a result I did not know what was
actually happening until other people started complaining about how their
icons looked like crap.
Container views with mini icons seemed to work as I expected. I create
the container with the CCS_MINIICONS class style and then put my mini
icon handle in the record's hptrIcon field instead of hptrMiniIcon. No
apparent scaling going on, although maybe under the hood it is doing the
scale up, then scale down scenario.
--
Reverse the parts of the e-mail address to reply by mail.
How do you create the icon itself that is assigned to hptrIcon? Is it
created from an <.ico> file at runtime? Or from a resource file at compile
time?
Can you elaborate on this technique a bit further. I came across this
bug very recently and I just re-used some code where the icons where
treated as BITMAPS when it was required. Still, I would like to use
the scaling trick better. Can you post a snippet?
Thanks
> Container views with mini icons seemed to work as I expected. I create
> the container with the CCS_MINIICONS class style and then put my mini
> icon handle in the record's hptrIcon field instead of hptrMiniIcon. No
> apparent scaling going on, although maybe under the hood it is doing the
> scale up, then scale down scenario.
If you specify a mini then give it a mini, PM has no reason to modify
it. Apparently you used a regular RECORDCORE struct and got the
desired results by putting the "wrong" handle in the right field.
I've only used MINIRECORDCOREs where there's just one HPTR field,
so I didn't have to play that game. What does PMMail use?
> > However, the resizing process appears to be symmetrical: �when you
> > display one of these bloated icons as a mini, PM will remove every
> > other line, giving you an exact replica of the original.
>
> Can you elaborate on this technique a bit further. I came across this
> bug very recently and I just re-used some code where the icons where
> treated as BITMAPS when it was required. Still, I would like to use
> the scaling trick better. Can you post a snippet?
As described, there's no technique or code to elaborate on. The source
data was a mini icon's bitmap & mask. When I duplicated it, the result
was an up-scaled full-size icon. When I wanted to display it elsewhere,
I told PM I wanted a mini icon but gave it the full-sized version. PM
down-scaled the icon for me, giving me an exact copy of the source,
which is what I wanted in the first place.
If you want to see some code that does this "manually", look at
> http://hg.mozilla.org/mozilla-central/file/ca31932ed41b/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp#l521
This converts the color bitmap of an OS/2 icon to a format usable
by Cairo. Note this method's 'fShrink' argument.
For an earlier, pre-Cairo version of this, see
> http://hg.mozilla.org/mozilla-central/file/9b2a99adc05e/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp#l530
Here, there are separate methods for converting & shrinking the bitmap.
In either case, the process is the same: skip every other line,
and on lines you keep, skip every other pixel.
So my question is: How do I create mini icons?
Is there really no API function that does so? The PM or WPS would seem
to indicate otherwise but I cannot find what to do.
In my case I compiled them into a DLL and loaded the resource.
If you're getting dithering or whatever, then you have another problem.
The most likely is a size mismatch, i.e. starting with a 16x16 or 32x32
icon on a system that requires a 20x20 or 40x40 icon. This would definitely
cause PM to interpolate pixels.
To confirm (once again) that the 16x16 -> 32x32 -> 16x16 conversion
does not produce any corruption, I modified an RWS-based app, Iconomize,
to use small rather than full-sized icons. I then compared the mini-icons
shown in WPS folders to those shown in the container control in Iconomize.
They were absolutely, pixel-for-pixel, identical.
> > > However, the resizing process appears to be symmetrical: when you
> > > display one of these bloated icons as a mini, PM will remove every
> > > other line, giving you an exact replica of the original.
> > >
> > That is not my experience. :-( Hence this posting.
> > If WinCreatePointerIndirect() is given mini icon images, it does not
> > scale them up by duplicating rows and columns. The method appears a
> > bit more advanced and involves shading or dithering or smoothing or
> > etc. When it then scales it down, the simpler method of removing every
> > other pixel is used. The result is undesirable.
>
> If you're getting dithering or whatever, then you have another problem.
Rich, are you sure you don't have SET ENH_STRETCH=NO turned on?
--
Alex Taylor
Fukushima, Japan
http://www.socis.ca/~ataylo00
Please take off hat when replying.
> Rich, are you sure you don't have SET ENH_STRETCH=NO turned on?
Ooops... I've had that in place for so long that I never thought about
it. When I removed it & rebooted, I found Jim is right: the result
of up-scaling then down-scaling does produce ugly mini icons.
Within one's own app like PMMail, it's possible to work around this
by adding SET ENH_STRETCH=NO to the end of the environment strings.
However, for RWS, I wouldn't consider messing with the WPS's
environment. I guess I'll have to come up with a new way to pass
mini icons between processes...
There's nothing to stop you from messing with the environment strings
(and I don't mean the C RTL environment, I mean the real thing). That's
what cmd.exe does when you use the SET command. Of course, if you want
to access the f/q exename or the app's commandline args, you'd better
do so before adding any strings. cmd.exe doesn't seem to care and just
overwrites them. (To demonstrate this, look at cmd.exe's environment
segment in Theseus, then add some strings at the commandline and look
again.)
The only question is when PM looks in the environment for this string.
It seems unlikely that it would do so before it actually needs to.
If so, you could add the string any time before you create your first
icon.
> Within one's own app like PMMail, it's possible to work around this
> by adding SET ENH_STRETCH=NO to the end of the environment strings.
> However, for RWS, I wouldn't consider messing with the WPS's
> environment. I guess I'll have to come up with a new way to pass
> mini icons between processes...
It's not really ideal in this case, as the setting will be inherited by
all child processes as well. In an email program, this includes any
time the user opens an attachment.
Since images are sent as email attachments fairly often, disabling
smooth scaling may have actual usability implications.
Whatever you do, you can undo: add the string, create the icons,
then replace the first letter of the string will a nul. No big deal.
I haven't tested this but that's what I'd try. While I had the
string remmed-out in config.sys, I did confirm that PM uses the
app's environment, not some global version (e.g. pmshell #1's).
That's why I think it should work.
Another thought: if you point WinLoadFileIcon() at a .ico file,
does it return that file's contents or the icon for .ico files?