A derive from latest update of Poffs. Small sample, showing how to use RTF
embedded in resource for a pretty nice About.. -dialog. Complete code, resource file,
RTF and compiled exe can be downloaded from: http://www.tolkenxp.com/pb/aboutbox.zip
Note: Updated April 24, now with OLE/COM interface for enabling pictures
and objects in embedded RTF document.
'------------------------------------------------------------------------------
Resource file, AboutBox.rc, looks like:
'------------------------------------------------------------------------------
Code looks like:
------------------
http://www.tolkenxp.com/pb
Download: incLean, PBcodec, custom controls and code, etc.
Borje Hagsten - [email protected]
[This message has been edited by Borje Hagsten (edited May 03, 2003).]
embedded in resource for a pretty nice About.. -dialog. Complete code, resource file,
RTF and compiled exe can be downloaded from: http://www.tolkenxp.com/pb/aboutbox.zip
Note: Updated April 24, now with OLE/COM interface for enabling pictures
and objects in embedded RTF document.
'------------------------------------------------------------------------------
Resource file, AboutBox.rc, looks like:
Code:
RTFABOUT RCDATA "AboutBox.rtf"
Code looks like:
Code:
#COMPILE EXE #RESOURCE "ABOUTBOX.PBR" #INCLUDE "WIN32API.INC" #INCLUDE "RICHEDIT.INC" '------------------------------------------------------------------------------ DECLARE CALLBACK FUNCTION DlgProc DECLARE CALLBACK FUNCTION AboutProc DECLARE SUB RichEditSetString (BYVAL hRichEdit AS DWORD) DECLARE SUB ShowAboutBox (BYVAL hParent AS DWORD) '------------------------------------------------------------------------------ %ID_RICHEDIT = 130 '------------------------------------------------------------------------------ GLOBAL gPos AS LONG, gPtr AS LONG, gTxt AS STRING 'for RichEdit stream-in.. '------------------------------------------------------------------------------ ' Declares for Rich Edit OLE stuff - to enable RTF with pictures and objects. ' If you don't need this ability, you can remove these declare and all routines ' from Reo_SetComInterface and down (ie, all OLE related stuff). '------------------------------------------------------------------------------ DECLARE FUNCTION Reo_SetComInterface(BYVAL hEdit AS DWORD) AS LONG 'used to initiate COM interface TYPE ReCbInterface 'UDT for the RichEdit callback interface pIntf AS DWORD PTR Refcount AS DWORD END TYPE ' This function creates a byte array object based on global memory DECLARE FUNCTION CreateILockBytesOnHGlobal LIB "OLE32.DLL" ALIAS _ "CreateILockBytesOnHGlobal" _ (BYVAL hGlobal AS DWORD, _ ' Memory handle allocated by the GlobalAlloc function BYVAL fDeleteOnRelease AS LONG, _ ' Determines whether the underlying handle for this _ ' byte array object should be automatically freed _ ' when the object is released. ppLkbyt AS DWORD) AS DWORD ' Address of ILockBytes pointer variable that receives ' the interface pointer to the new byte array object ' This function creates and opens a new compound file storage ' object on top of a byte array object provided by the caller DECLARE FUNCTION StgCreateDocfileOnILockBytes LIB "OLE32.DLL" ALIAS _ "StgCreateDocfileOnILockBytes" _ (plkbyt AS DWORD, _ ' Points to the ILockBytes interface on byte array object BYVAL grfMode AS DWORD, _ ' Specifies the access mode BYVAL reserved AS DWORD, _ ' Reserved; must be zero ppstgOpen AS DWORD) AS DWORD ' Points to loc for returning new storage obj '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Main entrance '------------------------------------------------------------------------------ FUNCTION PBMAIN LOCAL hDlg AS DWORD, hInst AS DWORD, hLib AS DWORD LOCAL lRes AS DWORD, lRes2 AS DWORD, lRes3 AS DWORD DIALOG NEW 0, "Press Enter, or click on About..",,, 390, 180, %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg ' OR %WS_THICKFRAME hLib = LoadLibrary("RICHED32.DLL") 'make sure RichEdit's dll is loaded IF hLib THEN hInst = GetModuleHandle("") 'need this to grab from resource lRes = FindResource(hInst, "RTFABOUT", BYVAL %RT_RCDATA) 'look for RTFABOUT in resource IF lRes THEN lRes2 = LoadResource(hInst, lRes) 'if found, load what we got IF lRes2 THEN lRes3 = LockResource(lRes2) 'lock to get a pointer to the RTF file IF lRes3 THEN gTxt = PEEK$(lRes3, SizeofResource(hInst, lRes)) 'load RTF into a global string END IF CONTROL ADD BUTTON, hDlg, %IDOK, " &About..", 280, 160, 50, 14 CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Quit", 334, 160, 50, 14 DIALOG SHOW MODAL hDlg, CALL DlgProc IF hLib THEN Freelibrary hLib END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Main dialog's message handler '------------------------------------------------------------------------------ CALLBACK FUNCTION DlgProc SELECT CASE CBMSG CASE %WM_INITDIALOG CASE %WM_COMMAND SELECT CASE CBCTL CASE %IDOK IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN ShowAboutBox CBHNDL 'show child dialog - here AboutBox dialog. END IF CASE %IDCANCEL 'respond to ESC key (or button with %IDCANCEL id) IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN DIALOG END CBHNDL END IF END SELECT END SELECT END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Child dialog's entrance '------------------------------------------------------------------------------ SUB ShowAboutBox (BYVAL hParent AS DWORD) LOCAL hDlg AS DWORD DIALOG NEW hParent, "About AboutBox..",,, 350, 150, %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg CONTROL ADD "RichEdit", hDlg, %ID_RICHEDIT, "", 5, 5, 341, 118, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR _ %ES_AUTOVSCROLL OR %ES_MULTILINE OR %ES_NOHIDESEL OR _ %ES_READONLY OR %ES_SAVESEL, %WS_EX_CLIENTEDGE Reo_SetComInterface GetDlgItem(hDlg, %ID_RICHEDIT) IF LEN(gTxt) THEN RichEditSetString GetDlgItem(hDlg, %ID_RICHEDIT) CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close", 294, 130, 50, 14 DIALOG SHOW MODAL hDlg, CALL AboutProc END SUB '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Child dialog's message handler '------------------------------------------------------------------------------ CALLBACK FUNCTION AboutProc SELECT CASE CBMSG CASE %WM_INITDIALOG CASE %WM_COMMAND SELECT CASE CBCTL CASE %IDCANCEL 'respond to ESC key (or button with %IDCANCEL id) IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN DIALOG END CBHNDL END SELECT END SELECT END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Insert a formatted RTF string into Rich Edit '------------------------------------------------------------------------------ SUB RichEditSetString (BYVAL hRichEdit AS DWORD) LOCAL eStream AS EDITSTREAM gPos = 1 'position in text to start from gPtr = STRPTR(gTxt) 'pointer to global text buffer eStream.pfnCallback = CODEPTR(RichEditStreamInString) 'pointer to RichEdit callback procedure SendMessage hRichEdit, %EM_STREAMIN, %SF_RTF, VARPTR(eStream) 'stream in text END SUB '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Rich Edit stream in callback - for streaming in string contents '------------------------------------------------------------------------------ FUNCTION RichEditStreamInString (BYVAL dwCookie AS DWORD, BYVAL pbBuff AS BYTE PTR, _ BYVAL cb AS LONG, pcb AS LONG) AS DWORD pcb = MIN&(cb, LEN(gTxt) - (gPos - 1)) 'number of bytes to copy IF pcb > 0 THEN 'copy block from global string directly into Richedit's buffer. CopyMemory pbBuff, (gPtr + gPos - 1), pcb 'could use POKE$ too, but this is a bit faster gPos = gPos + pcb 'incr pos for next callback position. END IF END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Here starts RichEdit OLE stuff - Initiate RichEdit's COM interface (OLE) '------------------------------------------------------------------------------ FUNCTION Reo_SetComInterface(BYVAL hEdit AS DWORD) AS LONG DIM pObj_RichCom AS DWORD PTR DIM pReCbIfc AS STATIC ReCbInterface DIM dwVTable(12) AS STATIC DWORD 'Initialize the OLE part. dwVTable( 0) = CODEPTR(Reo_QueryInterface) dwVTable( 1) = CODEPTR(Reo_AddRef) dwVTable( 2) = CODEPTR(Reo_Release) dwVTable( 3) = CODEPTR(Reo_GetNewStorage) dwVTable( 4) = CODEPTR(Reo_GetInPlaceContext) dwVTable( 5) = CODEPTR(Reo_ShowContainerUI) dwVTable( 6) = CODEPTR(Reo_QueryInsertObject) dwVTable( 7) = CODEPTR(Reo_DeleteObject) dwVTable( 8) = CODEPTR(Reo_QueryAcceptData) dwVTable( 9) = CODEPTR(Reo_ContextSensitiveHelp) dwVTable(10) = CODEPTR(Reo_GetClipboardData) dwVTable(11) = CODEPTR(Reo_GetDragDropEffect) dwVTable(12) = CODEPTR(Reo_GetContextMenu) pReCbIfc.pIntf = VARPTR(dwVTable(0)) pReCbIfc.Refcount = 1 FUNCTION = SendMessage(hEdit, %EM_SETOLECALLBACK, 0, VARPTR(pReCbIfc)) END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Methods of the IUnknown interface '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION Reo_QueryInterface (pObject AS DWORD PTR, REFIID AS DWORD, ppvObj AS DWORD) AS DWORD FUNCTION = %S_OK END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION Reo_AddRef (pObject AS DWORD PTR) AS DWORD INCR @pObject[1] FUNCTION = @pObject[1] END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION Reo_Release (pObject AS DWORD PTR) AS DWORD IF @pObject[1] > 0 THEN DECR @pObject[1] FUNCTION = @pObject[1] ELSE pObject = 0 END IF END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Methods of the IRichEditOleCallback interface ' Provides the application and document level interfaces and information ' required to support in-place activation '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION Reo_GetInPlaceContext (pObject AS DWORD PTR, lplpFrame AS DWORD, _ lplpDoc AS DWORD, lpFrameInfo AS DWORD) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Tells the application whether to display its container user interface '------------------------------------------------------------------------------ FUNCTION Reo_ShowContainerUI (pObject AS DWORD PTR, fShow AS LONG) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Queries the application as to whether an object should be inserted. '------------------------------------------------------------------------------ FUNCTION Reo_QueryInsertObject (pObject AS DWORD PTR, lpclsid AS DWORD, _ lpstg AS DWORD PTR, cp AS LONG) AS DWORD FUNCTION = %S_OK ' Yes, we'd love to have this object inserted END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Notification that an object is about to be deleted from a rich edit control '------------------------------------------------------------------------------ FUNCTION Reo_DeleteObject (pObject AS DWORD PTR, lpoleobj AS DWORD) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Called on a paste or drag to determine if the data pasted/dragged should be accepted '------------------------------------------------------------------------------ FUNCTION Reo_QueryAcceptData (pObject AS DWORD PTR, lpdataobj AS DWORD, _ lpcfFormat AS DWORD, reco AS DWORD, _ fReally AS LONG, hMetaPict AS DWORD) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Tells the application that it should transition into or out of context sensitive help mode '------------------------------------------------------------------------------ FUNCTION Reo_ContextSensitiveHelp (pObject AS DWORD PTR, fEnterMode AS LONG) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Allows the client to supply its own clipboard object '------------------------------------------------------------------------------ FUNCTION Reo_GetClipboardData (pObject AS DWORD PTR, lpchrg AS DWORD, _ reco AS DWORD, lplpdataobj AS DWORD) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Allows the client to specify the effects of a drop operation '------------------------------------------------------------------------------ FUNCTION Reo_GetDragDropEffect (pObject AS DWORD PTR, fDrag AS LONG, _ grfKeyState AS DWORD, pdwEffect AS DWORD) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Queries the application for a context menu to use on a right mouse down '------------------------------------------------------------------------------ FUNCTION Reo_GetContextMenu (pObject AS DWORD PTR, BYVAL seltype AS WORD, _ lpoleobj AS DWORD PTR, lpchrg AS CHARRANGE PTR, _ lphmenu AS DWORD) AS DWORD FUNCTION = %E_NOTIMPL END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ' Get storage interface for a new object '------------------------------------------------------------------------------ FUNCTION Reo_GetNewStorage (pObject AS DWORD PTR, lplpstg AS DWORD) AS DWORD LOCAL sc AS DWORD LOCAL lpLockBytes AS DWORD PTR ' Create a byte array in global memory - sc = CreateILockBytesOnHGlobal(BYVAL 0, BYVAL 1, lpLockBytes) IF sc THEN FUNCTION = sc : EXIT FUNCTION 'and a compound file storage object. sc = StgCreateDocfileOnILockBytes(@lpLockBytes, BYVAL %STGM_SHARE_EXCLUSIVE OR _ %STGM_READWRITE OR %STGM_CREATE, BYVAL 0, lplpstg) IF sc THEN CALL DWORD @@lpLockBytes[2] USING Reo_Release(@lpLockBytes) FUNCTION = sc END FUNCTION
------------------
http://www.tolkenxp.com/pb
Download: incLean, PBcodec, custom controls and code, etc.
Borje Hagsten - [email protected]
[This message has been edited by Borje Hagsten (edited May 03, 2003).]
Comment