Link to home
Start Free TrialLog in
Avatar of Darklion
Darklion

asked on

Generating irregularly-shaped dialogs?

I'd like to generate irregularly-shaped dialogs, such as ovals, circles, or combinations thereof (e.g., an oval shaped dialog with a bubble in one corner). How would I go about doing this? (Yes, I know there are ActiveX controls out there that will let me do it, but I don't have the money to purchase a collection of them.)
ASKER CERTIFIED SOLUTION
Avatar of psdavis
psdavis
Flag of United States of America 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
Avatar of helpmealot
helpmealot

It seems to me that Darklion is looking for irregularily shaped dialogs, not buttons.
I agree, Darklion, if you want to create an irregularily shaped dialog, look into the function SetWindowRgn.  I believe it provides the answer you are looking for.

If the current answer doesn't suit your needs, select the option "re-open question for other experts."  I can then provide the information you are looking for.
I have to agree as well.  I was leaving the office, saw the words irregularly shaped window and ActiveX controls and assumed that it was about Irregular shaped buttons, not dialogs.

Oh well, you know what they say when you "assume"?  You make an 'ass' out of 'u' and 'me'.

Phillip
Ok, ok, I hope this takes me off the hook! Here's some sites on the web talking about non-rectangular windows.  I hope THESE will help you instead!  I've ordered them from interesting to doubtful.  Good Luck this time!

Phillip



From: http://search.zdnet.com/pcmag/pctech/content/15/17/pp1517.006.html

Cool Graphics, Hot Code
Nonrectangular Windows

Continued from Figure 6

One of the most interesting of all the Win32 API functions is SetWindowRgn,
which converts an ordinary region into a "window region" that defines the
contour of a window. One use for SetWindowRgn is to create nonrectangular
windows like the one shown in Figure 8. The window is a top-level window
whose border and caption bar are hidden because they lie outside the window
 region. The region was created with ClipTextOutline from a string containing
 just one character--a 144-point version of character number 255 in the
 Wingdings character set. The window's client area is painted with a gradient
 fill that produces a red-to-black fade from top to bottom. A WM_NCHITTEST
 handler converts HTCLIENT hit-test codes into HTCAPTIONs so the window can
 be dragged by its client area. The end result is an unusual application
 whose window is a replica of the Windows logo. Because of space constraints,
 the source code is only available online.

You probably won't find many practical uses for such odd-shaped windows,
but they sure make for some eye-popping demos. And the very fact that it
can be done means somebody will find a use for it--guaranteed.


From: http://www.advantage.co.nz/ur/tamb.htm

No need to be square - Irregular Windows
By David Brebner
Pheeraphat Sawangphian (Tooh) contacted me, asking me how to make irregular
shaped windows. Well I have been really busy lately, (you can see by the
lack of recent additions to the site) and I had not had a chance to look
at how it was done. However Tooh got back to me with the problem solved.

Turns out it's pretty simple. There is a single API call, SetWindowRgn.
This sets the current window to any region you choose. Luckily the Windows
API also provides for very flexible region manipulation. Ellipse and polygons
can be combined to create irregular regions. These can be applied to the window
of your choice.

'Create some regions
rgn = CreateEllipticRgn(0, 0, 100, 100)
rgn2 = CreateRectRgn(50, 0, 100, 100)
rgn3 = CreateRoundRectRgn(90, 0, 150, 101, 10, 10)
rgn4 = CreateEllipticRgn(80, 50, 180, 150)


'add the regions together
tmp = CombineRgn(rgn, rgn, rgn2, RGN_OR)
tmp = CombineRgn(rgn, rgn, rgn3, RGN_OR)
tmp = CombineRgn(rgn, rgn, rgn4, RGN_OR)


'set the window to the result region
tmp = SetWindowRgn(Me.hWnd, rgn, True)

You can download my sample "pretend" Tamagotchi here.

Check our Tooh's Tamagotchi simulator http://202.44.194.10/members/tooh 

David Brebner
email dbrebner@hotmail.com



From: http://netserv.borland.com/devsupport/borlandcpp/ti/TI2927.html

KEYWORDS: non-rectangular windows round AREA: TI  
                    
Non-Rectangular Windows
=======================  
Windows 95 and NT let you create non-rectangular windows. For
example, run the Clock program that comes with Windows NT 3.51.
You make the non-rectangular region using CreateEllipticRgn() or
CreatePolygonRgn() . Then use SetWindowRgn() to display the
window in the new shape.  

The SetWindowRgn function sets the window region of the window.
The window region determines the area within the window where
the operating system permits drawing.  Windows will not display
any portion of the window that lies outside the region.
SetWindowRgn has a complementary function called GetWindowRgn.
GetWindowRgn obtains a copy of the window region of a window.  

Creating Non-Rectangular Windows
================================

The basic technique is very simple.  The example below is a basic
Window skeleton.  All the work of creating the non-rectangular
window is in the WM_CREATE message handler.  Notice that
SetProp() is used to help track the window.  Remember, before
processing the WM_DESTROY message, an application MUST use
RemoveProp() to remove all entries it added to a property list.  

Example
=======

The WM_DESTROY handler below is an example of properly destroying
the window.  

#include <windows.h>  

LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);  
char szWinName[] = "BasicWin";  

int WINAPI WinMain(HINSTANCE hCurrInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{    
      HWND     hWnd;
    MSG      msg;     WNDCLASS wc;      // define a window class
    wc.hInstance = hCurrInst;     wc.lpszClassName = szWinName;
    wc.lpfnWndProc =  WinProc;     wc.style = 0;       // default style
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);     wc.lpszMenuName = NULL;
    wc.cbClsExtra = 0;     wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);  

    if (!RegisterClass (&wc))        
            return 0;  

    hWnd = CreateWindow(szWinName,                        
                                    "Round Window",
                        WS_OVERLAPPEDWINDOW,// window style
                        CW_USEDEFAULT,      // X coordinate
                        CW_USEDEFAULT,      // Y coordinate
                        300,                // width
                        300,                // height
                        HWND_DESKTOP,       // no parent window
                        NULL,               // no menu
                        hCurrInst,          // handle of instance
                        NULL                // no additional args     );  

    ShowWindow(hWnd, nWinMode);    
      UpdateWindow(hWnd);  

    while(GetMessage(&msg, NULL, 0, 0))
      {        
            TranslateMessage(&msg);
        DispatchMessage(&msg);    
      }    
      
      return msg.wParam;
}  

LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{    
      switch(message)
      {        
      case WM_CREATE:
            {            
                  HRGN hRgn;
            RECT rect;              
                  GetClientRect(hWnd, &rect);
            hRgn = CreateEllipticRgn(0, 0, rect.right, rect.bottom);
            SetWindowRgn(hWnd, hRgn, TRUE);
            SetProp(hWnd, "region", hRgn);            
                  break;        
            }  
        case WM_DESTROY:            
                  if (GetProp(hWnd, "region"))
                  {
                DeleteObject(GetProp(hWnd, "region"));
                RemoveProp(hWnd, "region");            
                  }

            PostQuitMessage(0);            
                  break;          
            
            default:
            return DefWindowProc(hWnd, message, wParam, lParam);    
      }
    return 0;
}  

Now that you know how to create non-rectangular windows, you can
add a unique look to your application.



From: http://www.al-williams.com/awc/tip6.shtml

Did you know that under Windows 95 and Windows NT 3.51, you don't have to have rectangular windows? Define a normal region where point (0,0) is the top left corner of the window (not the client area). Then call SetWindowRgn() to set the region. Now the window will have the shape of the region.

Why do you want this capability? There are several reasons you might want to create an odd-shaped window. The classic example is a circular clock. What if you were writing a flowcharting program? You could make each flowchart element a separate child window of your main window. By using SetWindowRgn(), you can make the windows into any shape you like.

Here's some example code that sets up window to be triangular (sort of; see below).

void SetTriangleWin(HWND w)
  {
  HRGN rgn;
  POINT points[5];
  RECT wrect;
  SetWindowRgn(w,NULL,FALSE);
  GetWindowRect(w,&wrect);
  points[0].x=points[0].y=points[1].x=0;
  points[1].y=GetSystemMetrics(SM_CYMENU)+GetSystemMetrics(SM_CYCAPTION);
  points[3].x=points[4].x=wrect.right-wrect.left;
  points[4].y=0;
  points[3].y=GetSystemMetrics(SM_CYMENU)+GetSystemMetrics(SM_CYCAPTION);
  points[2].x=(wrect.right-wrect.left)/2;
  points[2].y=wrect.bottom-wrect.top;
  rgn=CreatePolygonRgn(points,5,WINDING);
  SetWindowRgn(w,rgn,TRUE);
  }


Good save, good save :-)
Thanks thresh, I've got a bad problem with that! :)

Avatar of Darklion

ASKER

Thanks, guys!