Solved

Background Transparent Bitmap Buttons

Posted on 1998-05-04
15
3,235 Views
Last Modified: 2013-12-03
Hello,
    I'm using VC5, and using the CBitmapButton class to get bitmaps on buttons
   but i also want the background of the image to be transparent, in effect getting
  a custom shaped buttons like circles and triangles rather than plain vanilla squares...
                                                                                                                 Pat b
 
0
Comment
Question by:hotsextoy
  • 5
  • 4
  • 4
  • +2
15 Comments
 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1399161
There are some classes at www.codeguru.com that lets you create triangle and circle buttons. Take a look there.

0
 
LVL 1

Author Comment

by:hotsextoy
ID: 1399162
Sorry bout that, but i was hope in for the actual Bitmap to make the shap of the button, not just circles, squares, triangles, (sorry if it was misleading...again i want to make the background of the bitmap transparent so that when i load it to the button with AutoLoad then the button would apear to have it's own shape...if that's possible...if there is an alternate method then i'm up for that to...anyways thanx
                                                                                    Pat b
0
 
LVL 23

Expert Comment

by:chensu
ID: 1399163
Then you cannot make use of CBitmapButton. You have to write your own button.
0
 
LVL 1

Author Comment

by:hotsextoy
ID: 1399164
hmm, i kinda figured that, just hopeing there was a faster way...thanx
                                                                                                 Pat b

0
 
LVL 2

Accepted Solution

by:
jstolan earned 160 total points
ID: 1399165
Here's how I did something similar.  I wanted an object which would look like a game piece, such as a chess piece.  I wrote an ActiveX control which used the CPictureHolder object with an icon as the "object" being held.  Icons of course have transparency as one of their available colors.

It worked great!  The ActiveX control will give you all of the button functionality you need and more.  You can easily determine if the user has clicked anywhere on the rectangular area of the control, or in the visible area of the icon.  The CPictureHolder will automatically draw and stretch the icon to whatever size you want.  Plus you can easily place and test your ActiveX control anywhere on a window, or in a dialog box using the resource editor.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1399166
I have code for owner-drawn transparent bitmap or icon buttons..

I can post this for you if you like.

Using icons makes it really very simple as the transparency is much easier to achieve.  With bitmaps you need a bit of extra code to draw transparently (or you can use an image list - but I haven't gotten around to changing my code to make use of them yet).

Would you like me to post the code up here???

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1399167
Creating an ActiveX control seems a lot more effort than (seems) required for what you want.

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 2

Expert Comment

by:jstolan
ID: 1399168
The ActiveX control is not difficult and it provides a LOT of functionality.  For example, it's trivial to determine if the user clicked on the rectangular area of the control or on the portion of the ICON which is actually visible.

My experience with these controls is you always want them to do just a little bit more.  ActiveX makes that very achievable.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1399169
OwnerDrawn buttons using DrawState lets you do things like show the button embossed or monochrome by setting style bits.  AFAIK CPictureHolder doesn't support that (you can simply render)

You can also just as easily detect where in the button rect the mouse was clicked (by responding to the mouse button down event).  I have buttons that do that, and changes appearance and the cursor as the mouse moves over them etc etc.

These could be wrapped up in an ActiveX control .. by I don't want to do the extra work involved.  Subclassing an existing button on a dialog (using ClassWizard) and doing the drawing and message handling (if requried) myself is just as easy.

0
 
LVL 1

Author Comment

by:hotsextoy
ID: 1399170
hmm, seems i have waged war of the roses here...and i'm kinda confused as to which way to go...both methods are foreign to me, ive actually never dealt with buttons using icons and haven't really messed with active x, either...i'll try the icon method tonight and see...but not quite sure what to look for...anyhow, i would like for u two to post or email me source code fore button transparencies...and any other button libs for that matter...(i also had intended them to move when clicked on, some buttons keep a down state when pressed, most of my buttons are supposed to act as a toggle like radio's in a set of buttons, and some other minor stuff) anyhow i kinda had ideas on how to do it all, except for the transparency part...but anyrate if u have code for other button states then please email me :
hotsextoy@hotmail.com         i'll also be willing give out all the points i have it's not much though (trust me)...anyhow thanx
Pat b
   
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1399171
Here is code cut from a more extensive icon button (the full code supports
* flat (IE) look, normal look or no button border.
* checked state (for radio-like button).
* icon, text or both
* dynamic cursor shape change over the button
* visited flag and color change (like a hyper link)
* text that can grows to fill the button
* text with a raised 3D appearance.

I can give you source that includes any/all of the above, However, this hacked version should just display an icon transparently, and show it greyed out if disabled.  It can be easily enhanced by adding to it, or deriving from it.

You use this by simple adding a button to you dialog and then using ClassWizard to create a control variable for it of class CIconButton.  Then you set the assiciated icon when you init the control variable in the dialog constructor.

Here's the code...

IconButton.h
============

#ifndef _QIconButton_
#define _QIconButton_

class QIconButton : public CButton {
  DECLARE_DYNAMIC(QIconButton)
public:
  QIconButton(UINT iconId=0)
    : CButton()
    , m_bDrawBackground(true)
    , m_iconId(iconId)
    , m_hicon(0)
  {}
  ~QIconButton() {
    if (m_hicon) {
      ::DestroyIcon(m_hicon);
    }
  }
  // icon
protected:
  UINT m_iconId;
  HICON m_hicon;
public:
  void SetIconId(UINT iconId);
  UINT IconId() const { return m_iconId; }
  // drawing
private:
  bool m_bDrawBackground;
protected:
  void Draw(CDC* pDC, const CRect& rect, UINT state=0);
protected:
  //{{AFX_MSG(QIconButton)
  afx_msg BOOL OnEraseBkgnd(CDC* pDC);
  //}}AFX_MSG
  //{{AFX_VIRTUAL(QIconButton)
  virtual void PreSubclassWindow();
  virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
  //}}AFX_VIRTUAL
  DECLARE_MESSAGE_MAP();
};
#endif

IconButton.cpp
==============

#include "stdafx.h"
#include "IconButton.h"

BEGIN_MESSAGE_MAP(QIconButton, CButton)
//{{AFX_MSG_MAP(QIconButton)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

IMPLEMENT_DYNAMIC(QIconButton,CButton)

void QIconButton::SetIconId(UINT iconId) {
  if (IconId() == iconId) return;
  m_iconId = iconId;
  if (m_hicon) ::DestroyIcon(m_hicon);
  m_hicon = NULL;
  if (GetSafeHwnd()) Invalidate();
}

void QIconButton::PreSubclassWindow() {
  SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW);
}

void QIconButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) {
  if (m_bDrawBackground) {
    m_bDrawBackground = false;
    // if not redrawing the whole thing,
    CWnd* pParent = GetParent();
    CRect rect; GetWindowRect(rect);
    pParent->ScreenToClient(rect);
    pParent->InvalidateRect(rect);
    pParent->UpdateWindow();
  } else {
    m_bDrawBackground = true;
    CDC* pDC = CDC::FromHandle(lpDIS->hDC);
    ASSERT_VALID(pDC);
    CRect rectClient = lpDIS->rcItem;
    Draw(pDC,rectClient,lpDIS->itemState);
  }
}

BOOL QIconButton::OnEraseBkgnd(CDC*) {
  return true;
}

void QIconButton::Draw(CDC* pDC, const CRect& rect, UINT state) {
  if (! m_hicon) {
    LPTSTR iconname = MAKEINTRESOURCE(IconId());
    HINSTANCE hinst = ::AfxFindResourceHandle(iconname,RT_GROUP_ICON);
    m_hicon = (HICON)::LoadImage(hinst,iconname,IMAGE_ICON,rect.Size().cx,rect.Size().cy,LR_DEFAULTCOLOR|LR_SHARED);
  }
  pDC->DrawState(rect.TopLeft(), rect.Size(), m_hicon, (state & ODS_DISABLED?DSS_DISABLED:DSS_NORMAL), (HBRUSH)NULL);
}

0
 
LVL 2

Expert Comment

by:jstolan
ID: 1399172
I'll send you an E-mail tonight.  It will have an ActiveX control called CPieces, should be pretty easy to modify into a button.  It's a little long to post here, and I can give you the whole project file.  

My only complaint with RonSlow's method is that it is going to be tricky determining if the user clicked on the visible icon or just in the control rectangle. Sure the mouse move will give you the position, but then you have to get the color underneath, etc.  But if you don't care about that, his method is probably easier (although a little less powerful).

BTW, you might consider changing your handle.  I had E-mail notification checked and my wife wanted to know who the hell "hotsextoy" was.  Fortunately the message was obviously pretty technical and boring.  LOL
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1399173
jstolan .. how does your control detect click on the icon .. the same technique could probably be used here as well.  It can certainly respond to clicks a different positions within the button .. (respond to Lbutton down rather than mouse move).

If hotsextoy is interested, I can send a fuller owner-drawn icon button class with the features mentioned.

0
 
LVL 2

Expert Comment

by:jstolan
ID: 1399174
Oops, I'm really embarrassed.

In fact the control I sent last night will respond when the user clicks anywhere in the rectangular region of the control.  I was thinking of an earlier version I did with circular and triangular buttons.  The control did a test on the point to determine if it was InCircle and InTriangle, and only responded if the test was positive.

A similar test could be done here for the icon, but it is not implemented.  A similar test could be added just as easily to Ronslow's button.  It sounds like Ronslow's button is probably closer to what you need.  It won't hurt my feelings if you reject my answer to give him the points.
0
 
LVL 1

Author Comment

by:hotsextoy
ID: 1399175
Thanx, guys about all this info, it's really been helpful...i haven't implemented yet but i have some time today so i'll try it out...I'm accepting ur answer cause i beleive in "e" for effort method.  But i think ROnslow's method is better, so i'll give him more points...anyways thanx to the both of u.
                                                                   Pat b

PS.  I thought about changeing my handle but i've had it for soo long, it kinda grows on you even when i myself grows up (i had it since high school) ..
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
This article surveys and compares options for encoding and decoding base64 data.  It includes source code in C++ as well as examples of how to use standard Windows API functions for these tasks. We'll look at the algorithms — how encoding and decodi…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now