November, 1995 - Vol. 2 No. 11
#include <owl/owlpch.h> #include <owl/edit.h> #include <owl/checkbox.h> #include <custcntl.h> #include "ctrltmpl.rh" char szClassName[] = "Template"; //============================================== // Custom control code //============================================== class _OWLCLASS TCustomControl : public TWindow { public: TCustomControl(HWND wnd, int AnId, CREATESTRUCT *lpCreate, TModule *Module = 0) :TWindow(wnd, Module) { Attr.Id = AnId; Attr.Style = lpCreate->style; Attr.ExStyle = lpCreate->dwExStyle; Attr.W = lpCreate->cx; Attr.H = lpCreate->cy; Attr.X = lpCreate->y; Attr.Y = lpCreate->x; SetBkgndColor(RGB(127,127,127)); } ~TCustomControl() { } virtual char * GetClassName() { return szClassName; } protected: UINT EvGetDlgCode(MSG far *) { return DLGC_WANTARROWS | DLGC_WANTCHARS; } void EvLButtonDown(uint, TPoint&) { MessageBeep(-1); } void EvPaint() { TPaintDC dc(*this); TRect& rect = *(TRect*)&dc.Ps.rcPaint; Paint(dc, dc.Ps.fErase, rect); } void Paint(TDC& dc, BOOL, TRect&); void CleanupWindow() { TWindow::CleanupWindow(); SetWindowLong(GWL_WNDPROC, (long)DefaultProc); } private: DECLARE_RESPONSE_TABLE(TCustomControl); }; DEFINE_RESPONSE_TABLE1(TCustomControl, TWindow) EV_WM_GETDLGCODE, EV_WM_LBUTTONDOWN, EV_WM_PAINT, END_RESPONSE_TABLE; void TCustomControl:: Paint(TDC& dc, BOOL bRepaint, TRect& r) { TWindow::Paint(dc, bRepaint, r); TBrush BackBrush(TWindow::BkgndColor); if (bRepaint) { dc.FillRect(r, BackBrush); } } //============================================== // Dialog editor and DLL code //============================================== struct StyleDialogBuf { char Name[CTLTITLE]; char ID[CTLTITLE]; WORD HScroll; WORD TabStop; WORD Disabled; WORD Visible; WORD VScroll; WORD Border; char Caption[CTLTITLE]; }; class _OWLCLASS TCustomControlDlg : public TDialog { public: TCustomControlDlg(TWindow *AParent, const char *AName, LPFNSTRTOID PStrToId, LPFNIDTOSTR PIdToStr, TModule *AModule); protected: LPFNIDTOSTR lpfnIdToStr; LPFNSTRTOID lpfnStrToId; TEdit* EdName; BOOL CanClose(); }; TCustomControlDlg:: TCustomControlDlg(TWindow *AParent, const char *AName, LPFNSTRTOID PStrToId, LPFNIDTOSTR PIdToStr, TModule *AModule) :TDialog(AParent, AName, AModule), lpfnStrToId(PStrToId), lpfnIdToStr(PIdToStr) { EdName = new TEdit(this, ID_EDNAME, CTLTITLE ); TStatic* st = new TStatic(this, ID_STIDVALUE, CTLTITLE ); st->EnableTransfer(); new TCheckBox(this, ID_HSCROLL); new TCheckBox(this, ID_TABSTOP); new TCheckBox(this, IDC_EDITABLE); new TCheckBox(this, ID_CKVISIBLE); new TCheckBox(this, ID_VSCROLL); new TCheckBox(this, ID_CKBORDER); new TEdit(this, ID_EDCAPTION, CTLTITLE); } BOOL TCustomControlDlg:: CanClose() { StyleDialogBuf* temp = (StyleDialogBuf*)TransferBuffer; if((*lpfnStrToId)(temp->Name)) return TRUE; return FALSE; } //============================================== // Style(), Flags(), and Info() //============================================== //extern "C" BOOL FAR PASCAL _export TemplateStyle(HWND HWindow, HANDLE hCtlStyle, LPFNSTRTOID StrToId, LPFNIDTOSTR IdToStr) { LPRWCTLSTYLE PStyle = (LPRWCTLSTYLE)GlobalLock( hCtlStyle ); BOOL ReturnValue = FALSE; TWindow RW_Window(HWindow); if (PStyle) { StyleDialogBuf TXBuffer; (*IdToStr)(PStyle->wId, TXBuffer.Name, CTLTITLE); strcpy(TXBuffer.Caption, PStyle->szTitle); itoa(PStyle->wId, TXBuffer.ID, 10); TXBuffer.HScroll = (PStyle->dwStyle & WS_HSCROLL) ? BF_CHECKED : BF_UNCHECKED; TXBuffer.VScroll = (PStyle->dwStyle & WS_VSCROLL) ? BF_CHECKED : BF_UNCHECKED; TXBuffer.Border = (PStyle->dwStyle & WS_BORDER) ? BF_CHECKED : BF_UNCHECKED; TXBuffer.Disabled = (PStyle->dwStyle & WS_DISABLED) ? BF_CHECKED : BF_UNCHECKED; TXBuffer.TabStop = (PStyle->dwStyle & WS_TABSTOP) ? BF_CHECKED : BF_UNCHECKED; TXBuffer.Visible = (PStyle->dwStyle & WS_VISIBLE) ? BF_CHECKED : BF_UNCHECKED; TCustomControlDlg PDlg(&RW_Window, (LPSTR)MAKEINTRESOURCE(CTRL_DLG), (LPFNSTRTOID)StrToId, (LPFNIDTOSTR)IdToStr, Module); PDlg.SetTransferBuffer(&TXBuffer); ReturnValue = ( IDOK == PDlg.Execute() ); if(ReturnValue) { PStyle->dwStyle &= ~(WS_HSCROLL | WS_VSCROLL | WS_BORDER | WS_DISABLED | WS_TABSTOP | WS_VISIBLE); if(TXBuffer.HScroll == BF_CHECKED) PStyle->dwStyle |= WS_HSCROLL; if(TXBuffer.VScroll == BF_CHECKED) PStyle->dwStyle |= WS_VSCROLL; if(TXBuffer.Border == BF_CHECKED) PStyle->dwStyle |= WS_BORDER; if(TXBuffer.Disabled == BF_CHECKED) PStyle->dwStyle |= WS_DISABLED; if(TXBuffer.TabStop == BF_CHECKED) PStyle->dwStyle |= WS_TABSTOP; if(TXBuffer.Visible == BF_CHECKED) PStyle->dwStyle |= WS_VISIBLE; PStyle->wId = HIWORD( (*StrToId)(TXBuffer.Name) ); } GlobalUnlock(hCtlStyle); } return ReturnValue; } //extern "C" WORD FAR PASCAL _export TemplateFlags( DWORD, LPSTR szBuf, WORD ) { wsprintf(szBuf,(LPSTR)"0"); return lstrlen(szBuf); } //extern "C" HANDLE FAR PASCAL _export TemplateInfo(void) { HANDLE hInfo = GlobalAlloc(GHND, sizeof(RWCTLINFO)); if ( hInfo ) { LPRWCTLINFO Info = (LPRWCTLINFO)GlobalLock(hInfo); Info->wVersion = 0x0100; Info->wCtlTypes = 1; lstrcpy(Info->szClass, szClassName); strcpy(Info->szTitle, szClassName); Info->Type[0].wType = 0; Info->Type[0].wWidth = 32; Info->Type[0].wHeight = 32; lstrcpy(Info->Type[0].szDescr, szClassName); Info->Type[0].dwStyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP ; Info->Type[0].hToolBit = LoadBitmap(Module->GetInstance(), MAKEINTRESOURCE(CTRL_BMP)); Info->Type[0].hDropCurs = LoadCursor(Module->GetInstance(), MAKEINTRESOURCE( IDC_CROSS )); GlobalUnlock(hInfo); } return hInfo; } //============================================== // ListClasses() //============================================== extern "C" HANDLE PASCAL _export ListClasses(LPSTR,// szAppName, WORD,// wVersion, LPFNLOADRES,// fnLoad, LPFNEDITRES)// fnEdit) { HANDLE hClasses = GlobalAlloc(GHND, sizeof(CTLCLASSLIST)); if(hClasses) { LPCTLCLASSLIST Classes = (LPCTLCLASSLIST)GlobalLock(hClasses); Classes->nClasses = 1; Classes->Classes[0].fnRWInfo = TemplateInfo; Classes->Classes[0].fnRWStyle = TemplateStyle; Classes->Classes[0].fnFlags = (LPFNFLAGS)TemplateFlags; lstrcpy(Classes->Classes[0].szClass, szClassName); GlobalUnlock(hClasses); } return hClasses; } //============================================== // Window procedure for the control //============================================== LONG FAR PASCAL _export TemplateWndProc(HWND HWindow, WORD wMsg, WORD wParam, LONG lParam) { CREATESTRUCT *lpCreate = (CREATESTRUCT*)lParam; if (wMsg == WM_CREATE) { int id = GetWindowWord(HWindow, GWW_ID); TWindow *Ctrl = new TCustomControl(HWindow, id, lpCreate, ::Module); SetWindowLong(HWindow, 0, (long)Ctrl); return 0; } else if (wMsg == WM_NCDESTROY) { TWindow *Ctrl = (TWindow*)GetWindowLong(HWindow, 0); delete Ctrl; return 0; } else return DefWindowProc(HWindow, wMsg, wParam, lParam); } static WNDCLASS wc = { CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS, (WNDPROC)TemplateWndProc, 0, 4, // Extra bytes for OWL pointer & RW flag 0, NULL, NULL, NULL, NULL, NULL }; //============================================== // Static TModule and LibMain //============================================== static TModule module("CTRLTMPL.DLL", FALSE); int FAR PASCAL LibMain( HINSTANCE hInstance, WORD, WORD wHeapSize, LPSTR lpszCmdLine ) { if( wHeapSize > 0 ) UnlockData(0); module.InitModule(hInstance, lpszCmdLine); ::Module = &module; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hInstance = hInstance; wc.lpszClassName = szClassName; return RegisterClass(&wc) ? TRUE : FALSE; }
Return to "Using OWL to create custom controls"
Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.