Link to home
Start Free TrialLog in
Avatar of rilucero
rilucero

asked on

'Disabling' bitmaps with the API

Hi all,

  I am in the process of developing a custom command button control and I'm having a little trouble with the graphical aspects of it.  My button is currently fully functional in that it raises events, draws edges, draws text and graphics and much more.   Right now, I have a property that allows me to set the graphic for the enabled position and the disabled position, and that works fine as well.  However, I would like to find a slicker solution to this so that the 'disabling' of the original bitmap graphic is done programatically.

  I have tried using the DRAWSTATE API function with the DST_BITMAP and DSS_DISABLED flags set.  This definitely changes the bitmap but the effect is less than desirable.  The bitmaps I'm sending into the function have a grey background and a very highly contrasted 'foreground.  What I'm looking for is a function that will keep the background the same colour and only apply the embossing to the foreground of the bitmap.  My feeling is that I need to make the bitmap transparent, convert it to mono and THEN emboss it.  Incidentally, the DST_ICON flag used with icons provides the exact effect I need but unfortunately, I need to use bitmaps.  

  Does anyone have any hints on how to generate a disabled effect on a bitmap that mimics a standard disabled windows icon?  Thanks for any suggestions!

Rafael
Avatar of inthedark
inthedark
Flag of United Kingdom of Great Britain and Northern Ireland image

Why not do ways with the command button completely and just build the image on a pciture box.

You could use the PaintPicture with a raster operation which would produce a diabled affect.

Back later....
Avatar of rilucero
rilucero

ASKER

Hi,

  I'm actually not using a command button.  All I have is a UserControl container and I'm rendering the bitmaps with the PaintPicture method.  This is working like a charm but my problem is 'disabling' the rendered bitmap.  Like I said, I already tried the DrawState API command but didn't like the results.  

  I'm not quite sure what you mean by using a 'raster effect' with PaintPicture.  My code for painting the bitmap right now is something like this:

UserControl.PaintPicture New_Picture, 0, 0, , , , , , , vbSrcCopy
 
How can I use PaintPicture to give me a disabled effect?

Rafael
Here is the process:

Yake a copy of your BTIMAP:

picCopy.Width=PicSource.Width
picCopy.Height=PicSource.Height
picCopy.PaintPicture picSource,0,0


Process the bitmap with the desired affect:

Create a single dimension safe arry pointer to the picture with a three byte matrix.

See for an example:

http://www.visualbasicforum.com/t25347.html 

The example at this site can be improved big-time I will show you how.

Instead of a bitmap with 2 dimensions I created a single dimensional array using a three byte element size:


Private Type PixelDef
  Blue As Byte
  Green As Byte
  Red As Byte
End Type

So you can loop throught the image like this:

Sub ProccessImage(Action As Actions)


Dim cp As Long
Dim Av As Long
Dim bt As Byte
Dim GreyFactor As Single

GreyFactor = 0.333333
cp = 0

Select Case Action
   
    Case Is = Actions.ConvertToGreyScale

    ' loop through image
    Do While cp < aSize ' asize is the size of the pic in pixels
        Av = (0& + Pixels(cp).Red + Pixels(cp).Green + Pixels(cp).Blue) * GreyFactor
        bt = Av
        Pixels(cp).Red = bt
        Pixels(cp).Green = bt
        Pixels(cp).Blue = bt
        cp = cp + 1
    Loop
   
    Case Is = Actions.GreyOutButtonImage
   
        Dim BackGround As PixelDef
       
        BackGround.Red = x ' set your background mask
        BackGround.Green = x ' set your background mask
        BackGround.Blue = x ' set your background mask
       
        ' loop through image
        Do While cp < aSize ' asize is the size of the pic in pixels
            GrayThisPixel = True
            Do
              If Pixels(cp).Red <> BackGround.Red Then Exit Do
              If Pixels(cp).Green <> BackGround.Green Then Exit Do
              If Pixels(cp).Blue <> BackGround.Blue Then Exit Do
   
              GrayThisPixel = False
              Exit Do
            Loop
            If GreyThisPixcel Then
                 Av = (0& + Pixels(cp).Red + Pixels(cp).Green + Pixels(cp).Blue) * GreyFactor
                 bt = Av
                 Pixels(cp).Red = bt
                 Pixels(cp).Green = bt
                 Pixels(cp).Blue = bt
            End If
            cp = cp + 1
        Loop

   
End Select

End Sub


ASKER CERTIFIED SOLUTION
Avatar of inthedark
inthedark
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
In simple terms the above code will be run on the copy of you bitmap.  It will then convert to greyscale only the part of the image which is not part of the background of the bitmap.

Hi inthedark,

  Thank you very much for the detailed response.  However, I'm still having a little problem.  It seems that no matter what bitmap I try to use with the LoadPicArray procedure, I get a bytes per pixel value of 4 which returns the colour resolution error message.  Here is what I'm doing.  I have a control called ToolButton which has a property called ToolPicture.  In a form, I have the following code:

Set ArcToolButton1.ToolPicture = LoadResPicture(106, 0)

The bitmap in the resource file is a 16 colour bitmap that I created in Paintshop Pro.

In my user control, I have a variable defined as:

dim m_ToolPicture as StdPicture

And in my ToolPicture property, I have:

Set m_ToolPicture = New_Picture

Finally, in the Enabled method of my user control, I use the LoadPicArray like this:

dim bLoaded as boolean
bLoaded = LoadPicArray(m_ToolPicture)
       

Like I said, every bitmap I have tried returns a pixel depth of 4.  Any ideas why this may be and how to fix the problem?  Thanks again!

Rafael
Hi rilucero,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Accept inthedark's comment(s) as an answer.

rilucero, if you think your question was not answered at all or if you need help, just post a new comment here; Community Support will help you.  DO NOT accept THIS comment as an answer.

EXPERTS: If you disagree with that recommendation, please post an explanatory comment.
==========
DanRollins -- EE database cleanup volunteer