Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!uunet!microsoft!matts From: matts@microsoft.UUCP (Matt SAETTLER) Newsgroups: comp.windows.ms Subject: Re: StillDown(), children, XOR mode Keywords: Mac-->Windows learning curve Message-ID: <57259@microsoft.UUCP> Date: 7 Sep 90 19:39:05 GMT References: <697@dbase.A-T.COM> Reply-To: matts@microsoft.UUCP (Matt SAETTLER) Organization: Microsoft Corp., Redmond WA Lines: 142 In article <697@dbase.A-T.COM> awd@dbase.A-T.COM (Alastair Dallas) writes: >I'm having all kinds of fun adapting my Macintosh skills to programming >Windows 3.0 (I think there are a lot of us doing that just now). I ran >into a slight problem and I thought I'd see what the net says. > >I'm writing an application that wants to drag a line around the screen. >So, when the window gets a WM_LBUTTONDOWN message, I call a routine which >tracks the mouse and repeatedly draws this line in XOR mode. On the Mac, >that would be something like: > > PenPat(patXOR); > while (StillDown()) > { > MoveTo(...); > LineTo(...); > } > >(more or less--much detail eliminated) > >Imagine my surprise to find nothing like StillDown() in the Windows API. >Fine, I thought, I'll suffice with something like Button(). But it's not >there, either. I ended up using PeekMessage(...WM_LBUTTONUP, WM_LBUTTONUP...). >First question: is this the preferred StillDown() approach? case WM_LBUTTONDOWN: SetCapture(hwnd); for (;;) // a long time { // just pay attention to MOUSE message. // if you want to get other message, change this. GetMessage(&msg,hwnd,WM_MOUSEFIRST,WM_MOUSELAST); if (msg.message == WM_MOUSEMOVE) { // Do Something... } else if (msg.message == xxx) { // Do Something else... } else if (msg.message == WM_LBUTTONUP) // the important one (don't forget it or else). break; } ReleaseCapture(); break; Of course, if you want to pay attention to lots of messages, you will want a switch. You also will want to put this into a routin if it grows by any more lines. > >Second question. What I'm doing is changing the size of two tiled child >windows. I have a parent window which is split horizontally by the two >child windows. I want the user to drag the line which divides the child >windows and thus change the size of both children simultaneously (since tiling >is a given). My problem is that the event is in reference to the parent >window (mouse movement can occur in either child window). However, getting >the DC for the parent and trying to draw there is apparently drawing >invisibly _behind_ the children. > The parent window probably has the WS_CLIPCHILDREN attribute, so you can't use the parent hwnd to draw over any children. (this is a good thing). You need to get the hwnd of the actual child window (try saving the list of children in the extra info of the parent HWND). You can size your sibling (MoveWindow(hSibling,...); and then UpdateWindow(hSibling);. Here's a neat trick. When you register the class, add some space for a data structure to the class: pClass->lpszClassName = BUTTONCLASS; [...] pClass->lpfnWndProc = ButtonWndProc; pClass->cbWndExtra = sizeof(HANDLE); ----------------------------------- Then, in an include file for the module: typedef struct { int flags; int importantinfo; HANDLE hData; } ButtonWinInfo; #define BUTTONINFO(hwnd) ( (ButtonWinInfo *)(GetWindowWord(hwnd,0))) #define BUTTONHWNDFLAGS(hwnd) (BUTTONINFO(hwnd)->flags) #define BUTTONHWNDINFO(hwnd) (BUTTONINFO(hwnd)->imortantinfo) #define BUTTONHWNDHDATA(hwnd) (BUTTONINFO(hwnd)->hData) ----------------------------------- Then, in ButtonWndProc: case WM_DESTROY: // Free our data structure (and any allocated items in it) GlobalFree(BUTTONHWNDHDATA(hWnd)); LocalFree((HANDLE)BUTTONINFO(hWnd)); break; case WM_CREATE: // Allocate a per-window data structure... h=LocalAlloc(LPTR, sizeof(ButtonWinInfo)); if(!h) return(NULL); // Since we allocated LPTR, the local handle is the local ptr. SetWindowWord(hWnd,0,h); // the macros are lvals and rvals BUTTONHWNDFLAGS(hWnd)= BUTTON_ALLOCATED | BUTTON_NEW; BUTTONHWNDINFO(hWnd) = important stuff; BUTTONHWNDHDATA(hWnd)=GlobalAlloc(GMEM_DISCARDABLE,DATA_SIZE); ... other create stuff break; (note that this code is for example only. I don't usually name things like this and ignore error conditions...) Another neat thing about this is that if you later decide that you want something to be global instead of window-specific, just do this: extern int gBflags; // The global flags for buttons... #define BUTTONHWNDFLAGS(hwnd) (gBflags) Also, if the structure is small, you may just want to add the structure to the WndExtra instead of using local memory: pClass->cbWndExtra = sizeof(ButtonWinInfo); and then change the macros appropriately. Good luck. I transitioned to Windows from the Mac way back in '86 with Windows 1.0.... with just the SDK for documentation.... It actually wasn't that bad. ----------------------------------- Matt Saettler I speak for myself; or so I'm told to say.