OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [libgui/] [src/] [tclsizebox.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* tclsizebox.c -- Tcl code to create a sizebox on Windows.
2
   Copyright (C) 1997, 1998 Cygnus Solutions.
3
   Written by Ian Lance Taylor <ian@cygnus.com>.  */
4
 
5
#ifdef _WIN32
6
 
7
#include <windows.h>
8
 
9
#include <tcl.h>
10
#include <tk.h>
11
 
12
#include "guitcl.h"
13
 
14
/* We need to make some Tk internal calls.  The only alternative is to
15
   actually move this code into Tk.  */
16
 
17
#include <tkWinInt.h>
18
 
19
/* These should really be defined in the cygwin32 header files.  */
20
 
21
#ifndef GetStockPen
22
#define GetStockPen(p) ((HPEN) GetStockObject (p))
23
#define GetStockBrush(b) ((HBRUSH) GetStockObject (b))
24
#define SelectPen(dc, p) (SelectObject (dc, (HGDIOBJ) p))
25
#define SelectBrush(dc, b) (SelectObject (dc, (HGDIOBJ) b))
26
#define DeleteBrush(b) (DeleteObject ((HGDIOBJ) b))
27
#endif
28
 
29
/* This file defines the Tcl command sizebox.
30
 
31
   sizebox PATHNAME [OPTIONS]
32
 
33
   Creates a sizebox named PATHNAME.  This accepts the standard window
34
   options.  This should be attached to the lower right corner of a
35
   window in order to work as expected.  */
36
 
37
/* We use
38
 
39
/* We use an instance of the structure as the Windows user data for
40
   the window.  */
41
 
42
struct sizebox_userdata
43
{
44
  /* The real window procedure.  */
45
  WNDPROC wndproc;
46
  /* The Tk window.  */
47
  Tk_Window tkwin;
48
};
49
 
50
/* The window procedure we use for a sizebox.  The default sizebox
51
   handling doesn't seem to erase the background if the sizebox is not
52
   exactly the correct size, so we handle that here.  */
53
 
54
static LRESULT CALLBACK
55
sizebox_wndproc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
56
{
57
  struct sizebox_userdata *su;
58
 
59
  su = (struct sizebox_userdata *) GetWindowLong (hwnd, GWL_USERDATA);
60
 
61
  switch (msg)
62
    {
63
    case WM_ERASEBKGND:
64
      /* The default sizebox handling doesn't seem to erase the
65
         background if the sizebox is not exactly the correct size, so
66
         we handle that here.  */
67
      if (Tk_Height (su->tkwin) != GetSystemMetrics (SM_CYHSCROLL)
68
          || Tk_Width (su->tkwin) != GetSystemMetrics (SM_CXVSCROLL))
69
        {
70
          HDC hdc = (HDC) wparam;
71
          RECT r;
72
          HPEN hpen;
73
          HBRUSH hbrush;
74
 
75
          GetClientRect (hwnd, &r);
76
          hpen = SelectPen (hdc, GetStockPen (NULL_PEN));
77
          hbrush = SelectBrush (hdc, GetSysColorBrush (COLOR_3DFACE));
78
          Rectangle (hdc, r.left, r.top, r.right + 1, r.bottom + 1);
79
          hbrush = SelectBrush (hdc, hbrush);
80
          DeleteBrush (hbrush);
81
          SelectPen (hdc, hpen);
82
          return 1;
83
        }
84
      break;
85
 
86
      /* We need to handle cursor handling here.  We also use Tk
87
         cursor handling via a call to Tk_DefineCursor, but we can't
88
         rely on it, because it will only take effect if Tk sees a
89
         MOUSEMOVE event which won't happen if the mouse moves
90
         directly from outside any Tk window to the sizebox.  */
91
    case WM_SETCURSOR:
92
      SetCursor (LoadCursor (NULL, IDC_SIZENWSE));
93
      return 1;
94
    }
95
 
96
  return CallWindowProc (su->wndproc, hwnd, msg, wparam, lparam);
97
}
98
 
99
/* This is called by the Tk dispatcher for various events.  */
100
 
101
static void
102
sizebox_event_proc (ClientData cd, XEvent *event_ptr)
103
{
104
  HWND hwnd = (HWND) cd;
105
  struct sizebox_userdata *su;
106
 
107
  if (! hwnd)
108
    return;
109
 
110
  if (event_ptr->type == DestroyNotify)
111
    {
112
      su = (struct sizebox_userdata *) GetWindowLong (hwnd, GWL_USERDATA);
113
      SetWindowLong (hwnd, GWL_USERDATA, 0);
114
      SetWindowLong (hwnd, GWL_WNDPROC, (LONG) su->wndproc);
115
      Tcl_Free ((char *) su);
116
      DestroyWindow (hwnd);
117
    }
118
}
119
 
120
/* Create a sizebox window.  */
121
 
122
static Window
123
sizebox_create (Tk_Window tkwin, Window parent, ClientData cd)
124
{
125
  POINT pt;
126
  Tk_Window parwin;
127
  HWND parhwnd;
128
  HWND hwnd;
129
  struct sizebox_userdata *su;
130
  Window result;
131
 
132
  /* We need to tell Windows that the parent of the sizebox is the
133
     toplevel which holds it.  Otherwise the sizebox will try to
134
     resize the child window, which doesn't make much sense.  */
135
 
136
  pt.x = Tk_X (tkwin);
137
  pt.y = Tk_Y (tkwin);
138
  ClientToScreen (TkWinGetHWND (parent), &pt);
139
 
140
  parwin = (Tk_Window) TkWinGetWinPtr (parent);
141
  while (! Tk_IsTopLevel (parwin))
142
    parwin = Tk_Parent (parwin);
143
  parhwnd = TkWinGetWrapperWindow (parwin);
144
 
145
  ScreenToClient (parhwnd, &pt);
146
 
147
  hwnd = CreateWindow ("SCROLLBAR", NULL,
148
                       WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP,
149
                       pt.x, pt.y, Tk_Width (tkwin), Tk_Height (tkwin),
150
                       parhwnd, NULL, Tk_GetHINSTANCE (), NULL);
151
 
152
  su = (struct sizebox_userdata *) Tcl_Alloc (sizeof *su);
153
  su->tkwin = tkwin;
154
  su->wndproc = (WNDPROC) GetWindowLong (hwnd, GWL_WNDPROC);
155
  SetWindowLong (hwnd, GWL_USERDATA, (LONG) su);
156
  SetWindowLong (hwnd, GWL_WNDPROC, (LONG) sizebox_wndproc);
157
 
158
  SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
159
               SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
160
 
161
  result = Tk_AttachHWND (tkwin, hwnd);
162
 
163
  Tk_CreateEventHandler (tkwin, StructureNotifyMask, sizebox_event_proc,
164
                         hwnd);
165
 
166
  return result;
167
}
168
 
169
/* The class procedure table for a sizebox widget.  This is an
170
   internal Tk structure.  */
171
 
172
static TkClassProcs sizebox_procs =
173
{
174
  sizebox_create,               /* createProc */
175
  NULL,                         /* geometryProc */
176
  NULL                          /* modalProc */
177
};
178
 
179
/* The implementation of the sizebox command.  */
180
 
181
static int
182
sizebox_command (ClientData cd, Tcl_Interp *interp, int argc, char **argv)
183
{
184
  Tk_Window tkmain;
185
  Tk_Window new;
186
  Tk_Cursor cursor;
187
 
188
  if (argc < 2)
189
    {
190
      Tcl_ResetResult (interp);
191
      Tcl_AppendStringsToObj(Tcl_GetObjResult (interp),
192
                             "wrong # args: should be \"",
193
                             argv[0], " pathname ?options?\"", (char *) NULL);
194
      return TCL_ERROR;
195
    }
196
 
197
  tkmain = Tk_MainWindow (interp);
198
  if (tkmain == NULL)
199
    return TCL_ERROR;
200
 
201
  new = Tk_CreateWindowFromPath (interp, tkmain, argv[1], (char *) NULL);
202
  if (new == NULL)
203
    return TCL_ERROR;
204
 
205
  Tk_SetClass (new, "Sizebox");
206
 
207
  /* This is a Tk internal function.  */
208
  TkSetClassProcs (new, &sizebox_procs, NULL);
209
 
210
  /* FIXME: We should handle options here, but we currently don't have
211
     any.  */
212
 
213
  Tk_GeometryRequest (new, GetSystemMetrics (SM_CXVSCROLL),
214
                      GetSystemMetrics (SM_CYHSCROLL));
215
 
216
  cursor = Tk_GetCursor (interp, new, Tk_GetUid ("size_nw_se"));
217
  if (cursor == None)
218
    return TCL_ERROR;
219
  Tk_DefineCursor (new, cursor);
220
 
221
  Tcl_SetResult (interp, Tk_PathName (new), TCL_STATIC);
222
  return TCL_OK;
223
}
224
 
225
/* Create the sizebox command.  */
226
 
227
int
228
ide_create_sizebox_command (Tcl_Interp *interp)
229
{
230
  if (Tcl_CreateCommand (interp, "ide_sizebox", sizebox_command, NULL,
231
                         NULL) == NULL)
232
    return TCL_ERROR;
233
  return TCL_OK;
234
}
235
 
236
#endif /* _WIN32 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.