summaryrefslogtreecommitdiffstats
path: root/private/ole2ui32/iconbox.cpp
blob: d18adb8be97c5d3e4aa504fd5130a98f5b44f6ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
 * ICONBOX.CPP
 *
 * Implemenatation of an IconBox control for OLE 2.0 UI dialogs that we'll
 * use wherever a dialog needs an icon/label display.  Through the control's
 * interface we can change the image or control label visibility.
 *
 * The IconBox discusses images in CF_METAFILEPICT format.  When drawing
 * such a metafile, the entire aspect is centered in the IconBox, so long
 * labels are chopped at either end.
 *
 * Copyright (c)1992 Microsoft Corporation, All Right Reserved
 */

#include "precomp.h"
#include "iconbox.h"
#include "utility.h"
#include "uiclass.h"

OLEDBGDATA

//Flag indicating if we've registered the class
static BOOL fRegistered;


/*
 * FIconBoxInitialize
 *
 * Purpose:
 *  Registers the IconBox control class.
 *
 * Parameters:
 *  hInst           HINSTANCE instance of the DLL.
 *
 *  hPrevInst       HINSTANCE of the previous instance.  Used to
 *                  determine whether to register window classes or not.
 *
 * Return Value:
 *  BOOL            TRUE if all initialization succeeded, FALSE otherwise.
 */

#pragma code_seg(".text$initseg")

BOOL FIconBoxInitialize(HINSTANCE hInst, HINSTANCE hPrevInst)
{
        // Only register class if we're the first instance
        if (hPrevInst)
                fRegistered = TRUE;
        else
        {
                // Static flag fRegistered guards against calling this function more
                // than once
                if (!fRegistered)
                {
                        WNDCLASS wc;
                        wc.lpfnWndProc   =IconBoxWndProc;
                        wc.cbClsExtra    =0;
                        wc.cbWndExtra    =CBICONBOXWNDEXTRA;
                        wc.hInstance     =hInst;
                        wc.hIcon         =NULL;
                        wc.hCursor       =LoadCursor(NULL, IDC_ARROW);
                        wc.hbrBackground =(HBRUSH)NULL;
                        wc.lpszMenuName  =NULL;
                        wc.style         =CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;

                        wc.lpszClassName = TEXT(SZCLASSICONBOX1);
                        fRegistered = RegisterClass(&wc);

                        wc.lpszClassName = TEXT(SZCLASSICONBOX2);
                        fRegistered = RegisterClass(&wc);

                        wc.lpszClassName = TEXT(SZCLASSICONBOX3);
                        fRegistered = RegisterClass(&wc);
                }
        }
        return fRegistered;
}

#pragma code_seg()


/*
 * IconBoxUninitialize
 *
 * Purpose:
 *  Cleans up anything done in FIconBoxInitialize.  Currently there is
 *  nothing, but we do this for symmetry.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  None
 */

void IconBoxUninitialize(void)
{
        return;
}

/*
 * IconBoxWndProc
 *
 * Purpose:
 *  Window Procedure for the IconBox custom control.  Only handles
 *  WM_CREATE, WM_PAINT, and private messages to manipulate the image.
 *
 * Parameters:
 *  Standard
 *
 * Return Value:
 *  Standard
 */

LONG CALLBACK IconBoxWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
        //Handle standard Windows messages.
        switch (iMsg)
        {
        case WM_CREATE:
                SetWindowLong(hWnd, IBWW_HIMAGE, 0);
                SetWindowWord(hWnd, IBWW_FLABEL, TRUE);
                return 0L;

        case WM_ERASEBKGND:
                {

                        RECT rect;
                        GetClientRect(hWnd, &rect);
                        HBRUSH hBrush = (HBRUSH)SendMessage(GetParent(hWnd), WM_CTLCOLORDLG,
                                wParam, (LPARAM)GetParent(hWnd));

                        if (!hBrush)
                                return FALSE;

                        UnrealizeObject(hBrush);

                        SetBrushOrgEx((HDC)wParam, 0, 0, NULL);
                        FillRect((HDC)wParam, &rect, hBrush);
                        return TRUE;
                }

        case WM_PAINT:
                {
                        HGLOBAL hMF = (HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE);

                        //BeginPaint and EndPaint clear us even if hMF is NULL.
                        PAINTSTRUCT ps;
                        HDC hDC = BeginPaint(hWnd, &ps);

                        if (NULL != hMF)
                        {
                                //Now we get to paint the metafile, centered in our rect.
                                RECT rc;
                                GetClientRect(hWnd, &rc);

                                /*
                                 * If we're doing icon only, then place the metafile
                                 * at the center of our box minus half the icon width.
                                 * Top is top.
                                 */
                                BOOL fLabel = GetWindowWord(hWnd, IBWW_FLABEL);

                                //Go draw where we decided to place it.
                                OleUIMetafilePictIconDraw(hDC, &rc, hMF, !fLabel);
                        }
                        EndPaint(hWnd, &ps);
                }
                break;

        case IBXM_IMAGESET:
                {
                        /*
                         * wParam is a flag to delete the old or not.
                         * lParam contains the new handle.
                         */
                        HGLOBAL hMF = (HGLOBAL)SetWindowLong(hWnd, IBWW_HIMAGE, lParam);
                        InvalidateRect(hWnd, NULL, TRUE);
                        UpdateWindow(hWnd);

                        //Delete the old handle if requested
                        if (0L!=wParam)
                        {
                                OleUIMetafilePictIconFree(hMF);
                                hMF=NULL;
                        }
                        return (LONG)(UINT)hMF;
                }

        case IBXM_IMAGEGET:
                {
                        //Return the current index.
                        HGLOBAL hMF=(HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE);
                        return (LONG)(UINT)hMF;
                }

        case IBXM_IMAGEFREE:
                {
                        //Free up whatever we're holding.
                        HGLOBAL hMF=(HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE);
                        OleUIMetafilePictIconFree(hMF);
                        SetWindowLong(hWnd, IBWW_HIMAGE, 0);
                        return 1L;
                }

        case IBXM_LABELENABLE:
                //wParam has the new flag, returns the previous flag.
                return (LONG)SetWindowWord(hWnd, IBWW_FLABEL, (WORD)wParam);

        default:
                return DefWindowProc(hWnd, iMsg, wParam, lParam);
        }

        return 0L;
}