You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
Lets say I want to add a watermark to a jpeg to protect an image (Or in this case a piece of software until the software is registered)...
Scott Turchin
MCSE, MCP+I http://www.tngbbs.com
---------------------- True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi
Normally text or, better, any kind of meta data is added via Exif tags.
But if you want something a little bit more subtle (but not, by any mean, really effective as a watermark) you can also simply add some bytes at the end of the file, after the last 0xFF 0xD9 bytes.
The bitmap will continue to be read correctly by almost any software, and you have some bytes moderately hidden, at least to the casual viewer.
Oh I don't want the text hidden, I want it to say "UNREGISTERED SHAREWARE VERSION" All over it
I'd like to mix it
Scott Turchin
MCSE, MCP+I http://www.tngbbs.com
---------------------- True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi
Not sure, but I think Scott means kinda like National Instruments "Labview" that puts a silhouette of their insignia in the bottom right of their apps in Forms/Dialogs/Windows that are made with shareware or trial programs
Kind of like "If you like it...buy it.....If you don't...then do not use it"
It helps somewhat with sales, and is somewhat not annoying as other techniques. And a DEFINITE tip-off when supporting a call or email or other that turns out is a user that wants something for nothing.
I could be off...but I think the generic premise is true
Engineer's Motto: If it aint broke take it apart and fix it
"If at 1st you don't succeed... call it version 1.0"
"Half of Programming is coding"....."The other 90% is DEBUGGING"
"Document my code????" .... "WHYYY??? do you think they call it CODE? "
Taking my own medicine, I tried to draw some text on a picture using GDIP. So far I have failed. The basic code to display the picture works fine, but the text drawing bit does not. I'm going to turn in now (it's late here), I will leave some copileable code just in case there is a GDIP wizard out there who can spot the obvious mistake ( all changes are in the in the WM_ERASEBKGND handler)
Code:
' A very simple application which displays a picture file chosen by the user.
' Uses GDIPLUS and includes error reporting using GDIplus status codes
' PB Win 8.04, no dependencies except standard INCLUDES.
'
' Chris Holbrook 1 August 2008
'
' 5-AUG-2008 revised WM_ERASEBKGND handler
' 21-OCT-2008 trying out adding text to the picture see WM_ERASEBKGND handler!
'
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC"
#INCLUDE "comdlg32.inc"
%IDD_DIALOG1 = 101
%IDC_getpic_bn = 1004
'------------------------------------------------------------------------------
' GDI+ status (error) codes
%StatusOk = 0
%StatusGenericError = 1
%StatusInvalidParameter = 2
%StatusOutOfMemory = 3
%StatusObjectBusy = 4
%StatusInsufficientBuffer = 5
%StatusNotImplemented = 6
%StatusWin32Error = 7
%StatusWrongState = 8
%StatusAborted = 9
%StatusFileNotFound = 10
%StatusValueOverflow = 11
%StatusAccessDenied = 12
%StatusUnknownImageFormat = 13
%StatusFontFamilyNotFound = 14
%StatusFontStyleNotFound = 15
%StatusNotTrueTypeFont = 16
%StatusUnsupportedGdiplusVersion = 17
%StatusGdiplusNotInitialized = 18
%StatusPropertyNotFound = 19
%StatusPropertyNotSupported = 20
'---------------------------------------------------------------------
TYPE GdiplusStartupInput
GdiplusVersion AS DWORD '// Must be 1
DebugEventCallback AS DWORD '// Ignored on free builds
SuppressBackgroundThread AS LONG '// FALSE unless you're prepared to call
'// the hook/unhook functions properly
SuppressExternalCodecs AS LONG '// FALSE unless you want GDI+ only to use
'// its internal image codecs.
END TYPE
'---------------------------------------------------------------------
'
TYPE GdiplusStartupOutput
' // The following 2 fields are NULL if SuppressBackgroundThread is FALSE.
' // Otherwise, they are functions which must be called appropriately to
' // replace the background thread.
' //
' // These should be called on the application's main message loop - i.e.
' // a message loop which is active for the lifetime of GDI+.
' // "NotificationHook" should be called before starting the loop,
' // and "NotificationUnhook" should be called after the loop ends.
NotificationHook AS DWORD
NotificationUnhook AS DWORD
END TYPE
'
DECLARE FUNCTION GdipDrawImageRectI LIB "gdiplus.dll" ALIAS "GdipDrawImageRectI" (BYVAL graphics AS LONG, BYVAL nImage AS LONG, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL nWidth AS LONG, BYVAL Height AS LONG) AS LONG
DECLARE FUNCTION GdipDeleteGraphics LIB "gdiplus.dll" ALIAS "GdipDeleteGraphics" (BYVAL graphics AS LONG) AS LONG
DECLARE FUNCTION GdipCreateFromHDC LIB "gdiplus.dll" ALIAS "GdipCreateFromHDC" (BYVAL hdc AS LONG, graphics AS LONG) AS LONG
DECLARE FUNCTION GdipGetImagePixelFormat LIB "gdiplus.dll" ALIAS "GdipGetImagePixelFormat" _
(BYVAL nImage AS LONG, PixelFormat AS LONG) AS LONG
DECLARE FUNCTION GdipGetImageDimension LIB "gdiplus.dll" ALIAS "GdipGetImageDimension" _
(BYVAL nImage AS LONG, nWidth AS SINGLE, Height AS SINGLE) AS LONG
DECLARE FUNCTION GdiplusStartup LIB "GDIPLUS.DLL" ALIAS "GdiplusStartup" _
(token AS DWORD, inputbuf AS GdiplusStartupInput, outputbuf AS GdiplusStartupOutput) AS LONG
DECLARE SUB GdiplusShutdown LIB "GDIPLUS.DLL" ALIAS "GdiplusShutdown" _
(BYVAL token AS DWORD)
DECLARE FUNCTION GdipLoadImageFromFile LIB "GDIPLUS.DLL" ALIAS "GdipLoadImageFromFile" _
(BYVAL flname AS STRING, lpImage AS DWORD) AS LONG
DECLARE FUNCTION GdipDisposeImage LIB "GDIPLUS.DLL" ALIAS "GdipDisposeImage" _
(BYVAL lpImage AS DWORD) AS LONG
DECLARE FUNCTION GdipDrawString LIB "GDIPLUS.DLL" ALIAS "GdipDrawString" _
(BYVAL graphics AS DWORD, BYVAL pString AS STRING, BYVAL length AS LONG, BYVAL pFont AS DWORD, _
BYREF layoutRect AS Rect, BYVAL stringFormat AS DWORD, BYVAL brush AS DWORD ) AS LONG
DECLARE FUNCTION GdipCreateStringFormat LIB "GDIPLUS.DLL" ALIAS "GdipCreateStringFormat" _
( BYVAL formatAttributes AS LONG, BYVAL language AS WORD, BYREF pFormat AS DWORD ) AS LONG
DECLARE SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG, _ picture dimensions
BYVAL xCell AS LONG, BYVAL yCell AS LONG, _ FRAME dimensions
BYREF xOfs AS LONG, BYREF yOfs AS LONG, _ calc'd offset in frame
BYREF xSize AS LONG, BYREF ySize AS LONG) ' thumbnail dimensions
'-------------------------------------------------------------------------------------------------------
' Computes location and size to stretch a bitmap preserving its aspect.
'
SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG, _ picture dimensions
BYVAL xCell AS LONG, BYVAL yCell AS LONG, _ FRAME dimensions
BYREF xOfs AS LONG, BYREF yOfs AS LONG, _ calc'd offset in frame
BYREF xSize AS LONG, BYREF ySize AS LONG) EXPORT ' thumbnail dimensions
LOCAL SCALE AS SINGLE
IF xPIC& THEN scale! = xCell& / xPic&
IF scale! > 1 THEN scale! = 1
xSize& = xPic& * scale!: ySize& = yPic& * scale!
' In case Height > 150 compute new scale factor
IF ySize& > yCell& THEN
IF yPic& THEN scale! = yCell& / yPic&
xSize& = xPic& * scale!: ySize& = yPic& * scale!
END IF
xOfs& = (xCell& - xSize&) \ 2
yOfs& = (yCell& - ySize&) \ 2
END SUB
'---------------------------------------------------------------------
' get image filename
FUNCTION getpic (hD AS LONG) AS STRING
LOCAL buf, spath, sfile AS STRING
LOCAL dwstyle AS DWORD
LOCAL hFile AS LONG
dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
Buf = "Picture files (*.JPG,*.PNG,*.TIF,*.ICO,*.GIF,*.BMP)|*.JPG|*.PNG|*.TIF|*.ICO|*.PNG|*.BMP|"
sfile = "*.JPG;*.PNG;*.TIF;*.ICO;*.GIF;*.BMP"
IF OpenFileDialog (hD, "Locate image file ", sfile, spath, buf, "JPG", dwstyle) = 0 THEN
EXIT FUNCTION
END IF
FUNCTION = sfile
END FUNCTION
'----------------------------------------------------------------------
FUNCTION MakeFont(BYVAL fName AS STRING, BYVAL ptSize AS LONG, _
OPT BYVAL attr AS STRING) AS DWORD
'--------------------------------------------------------------------
' Create a desired font and return its handle.
' attr = "biu" for bold, italic, and underlined (any order)
'--------------------------------------------------------------------
LOCAL hDC AS DWORD, CharSet AS LONG, CyPixels AS LONG
LOCAL BOLD, italic, uLine AS LONG
IF LEN(attr) THEN
IF INSTR(LCASE$(attr), "b") THEN BOLD = %FW_BOLD
IF INSTR(LCASE$(attr), "i") THEN italic = 1
IF INSTR(LCASE$(attr), "u") THEN uLine = 1
END IF
hDC = GetDC(%HWND_DESKTOP)
CyPixels = GetDeviceCaps(hDC, %LOGPIXELSY)
ReleaseDC %HWND_DESKTOP, hDC
PtSize = 0 - (ptSize * CyPixels) \ 72
FUNCTION = CreateFont(ptSize, 0, 0, 0, BOLD, italic, uLine, _
%FALSE, CharSet, %OUT_TT_PRECIS, _
%CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _
%FF_DONTCARE , BYCOPY fName)
END FUNCTION
'------------------------------------------------------------------------
' callback function for dialog on which the image is displayed
'
CALLBACK FUNCTION PicDlgCB()
STATIC sPicPath AS STRING
STATIC himage AS DWORD
LOCAL pGraphics AS DWORD
LOCAL hdc, hfont, hbrush, strformat AS DWORD
LOCAL r AS rect
LOCAL lPixelFormat AS LONG
LOCAL l, framex, framey AS LONG
STATIC ofsx, ofsy, tX, tY AS LONG
LOCAL maxwidth, maxheight AS LONG
LOCAL origwidth, origheight AS SINGLE
STATIC sGDIPStatusCodes() AS STRING ' table of error codes referenced by GDIP status codes
LOCAL sGDIPfn AS STRING ' GDIP function name for error reporting
LOCAL sz AS ASCIZ * 16
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' initialise static variables
himage = 0: ofsx = 0: ofsy = 0: tX = 0: tY = 0
' create font
hfont = makefont ("Courier New", 10, "")
' load GDIPlus error messages
GOSUB LoadGDIPERMS
'
CASE %WM_ERASEBKGND
IF himage = 0 THEN FUNCTION = 0 : EXIT SELECT
hdc = getdc(CBHNDL)
IF GdipCreatefromHDC ( hDC, pGraphics) = 0 THEN
l = GdipDrawImageRectI(pGraphics, himage, ofsX, ofsY, tX, tY)
IF l THEN sGDIPfn = "GdipDrawImageRectI": GOSUB gdiperror
END IF
sz = UCODE$("hello!")
setrect BYVAL VARPTR(r), 10, 10, 100, 100
hBrush = SelectObject(hDC, GetStockObject(%NULL_BRUSH))
' Create the StringFormat object
' We can pass NULL for the flags and language ID if we want
CALL GdipCreateStringFormat(0, 0, strFormat)
GdipDrawString ( pgraphics, sz, 1, hfont, r, 0, BYVAL 0)
l = gdipdeletegraphics(pgraphics)
IF l THEN sGDIPfn = "gdipdeletegraphics": GOSUB gdiperror
FUNCTION = 1
'
CASE %WM_USER + 401
spicpath = UCODE$(GetPic(CBHNDL))
getClientrect(CBHNDL, r)
IF himage THEN gdipdisposeimage (himage)
l = GDIPLoadImageFromFile (BYVAL spicPath , BYREF hImage)
IF l THEN sGDIPfn = "GDIPLoadImageFromFile": GOSUB gdiperror
IF hImage = 0 THEN EXIT SELECT
' get image height, width & pixel format
l = GdipGetImageDimension (BYVAL hImage, BYREF origwidth, BYREF origheight)
IF l THEN sGDIPfn = "GdipGetImageDimension": GOSUB gdiperror
maxwidth = r.nright - r.nleft : maxheight = r.nbottom - r.ntop
l = GdipGetImagePixelFormat (BYVAL hImage, BYREF lPixelFormat)
IF l THEN sGDIPfn = "GdipGetImagePixelFormat": GOSUB gdiperror
' derive new image size for display on the dailog, preserving aspect ratio
' the results are declared STATIC so that the %WM_ERASEBKGND handler can use them
skIconise ( BYVAL origwidth, BYVAL origheight, BYVAL maxwidth, BYVAL maxheight, _
BYREF ofsX, BYREF ofsY, BYREF tX, BYREF tY)
' force redraw via WM_ERASEBKGND
invalidaterect CBHNDL, r, %TRUE
'
CASE %WM_DESTROY
IF himage THEN
deleteobject ( hfont)
l = gdipdisposeimage(himage)
IF l THEN sGDIPfn = "GdipDisposeImage": GOSUB gdiperror
END IF
'
END SELECT
EXIT FUNCTION
''''''''''''''''''''''
gdiperror:
? sGDIPfn + ":" + sGDIPStatusCodes(l)
EXIT FUNCTION
RETURN
''''''''''''''''''''''
LoadGDIPERMS:
DIM sGDIPStatusCodes(0 TO 20) AS STATIC STRING
sGDIPStatusCodes(%StatusOk ) = "Ok
sGDIPStatusCodes(%StatusGenericError ) = "Generic Error
sGDIPStatusCodes(%StatusInvalidParameter ) = "Invalid Parameter
sGDIPStatusCodes(%StatusOutOfMemory ) = "Out Of Memory
sGDIPStatusCodes(%StatusObjectBusy ) = "Object Busy
sGDIPStatusCodes(%StatusInsufficientBuffer ) = "Insufficient Buffer
sGDIPStatusCodes(%StatusNotImplemented ) = "Not Implemented
sGDIPStatusCodes(%StatusWin32Error ) = "Win32 Error
sGDIPStatusCodes(%StatusWrongState ) = "Wrong State
sGDIPStatusCodes(%StatusAborted ) = "Aborted
sGDIPStatusCodes(%StatusFileNotFound ) = "File Not Found
sGDIPStatusCodes(%StatusValueOverflow ) = "Value Overflow
sGDIPStatusCodes(%StatusAccessDenied ) = "Access Denied
sGDIPStatusCodes(%StatusUnknownImageFormat ) = "Unknown Image Format
sGDIPStatusCodes(%StatusFontFamilyNotFound ) = "Font Family Not Found
sGDIPStatusCodes(%StatusFontStyleNotFound ) = "Font Style Not Found
sGDIPStatusCodes(%StatusNotTrueTypeFont ) = "Not TrueType Font
sGDIPStatusCodes(%StatusUnsupportedGdiplusVersion ) = "Unsupported Gdiplus Version
sGDIPStatusCodes(%StatusGdiplusNotInitialized ) = "Gdiplus Not Initialized
sGDIPStatusCodes(%StatusPropertyNotFound ) = "Property Not Found
sGDIPStatusCodes(%StatusPropertyNotSupported ) = "Property Not Supported
RETURN
END FUNCTION
'------------------------------------------------------------------------
' main dialog callback function
'
CALLBACK FUNCTION MainDlgCB()
LOCAL s AS STRING
STATIC hPicWnd AS DWORD
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' create another dialog on which the image will be displayed.
' It didn't have to be a dialog, but if a control in the main dialog
' was used then it would have to be sub- or super-classed to receive its
' own WM_ERASEBKGND messages. This is just the easiest (DDT) way to do it.
DIALOG NEW CBHNDL, "", 85, 5, 190, 125, %WS_POPUP OR %WS_BORDER OR _
%WS_POPUP OR %WS_CHILD OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
%DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
%WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hPicWnd
DIALOG SHOW MODELESS hPicWnd, CALL PicDlgCB 'TO lRslt
CASE %WM_COMMAND
SELECT CASE AS LONG CBCTL
CASE %IDC_getpic_bn
IF HI(WORD,CBWPARAM) = %BN_CLICKED THEN
sendmessage hPicWnd, %WM_USER + 401, 0, 0
END IF
END SELECT
END SELECT
END FUNCTION
'------------------------------------------------------------------
FUNCTION MainDlg(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG
LOCAL hDlg AS DWORD
DIALOG NEW hParent, "using GDI+ example 1", 139, 129, 279, 135, _
%WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
%DS_NOFAILCREATE OR %DS_SETFONT, _
%WS_EX_CONTROLPARENT, TO hDlg
CONTROL ADD BUTTON, hDlg, %IDC_getpic_bn, "find a picture", 5, 5, 75, 15
DIALOG SHOW MODAL hDlg, CALL MainDlgCB TO lRslt
FUNCTION = lRslt
END FUNCTION
'=======================================================================
FUNCTION PBMAIN()
STATIC nstatus AS LONG
STATIC token AS DWORD
STATIC StartupInput AS GdiplusStartupInput
StartupInput.GdiplusVersion = 1
nStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
IF nStatus THEN
MSGBOX "Error initializing GDI+", %mb_applmodal, "Warning"
EXIT FUNCTION
END IF
MainDlg %HWND_DESKTOP
GdiplusShutdown token
END FUNCTION
Not sure, but I think Scott means kinda like National Instruments "Labview" that puts a silhouette of their insignia in the bottom right of their apps in Forms/Dialogs/Windows that are made with shareware or trial programs
Kind of like "If you like it...buy it.....If you don't...then do not use it"
It helps somewhat with sales, and is somewhat not annoying as other techniques. And a DEFINITE tip-off when supporting a call or email or other that turns out is a user that wants something for nothing.
I could be off...but I think the generic premise is true
This is correct, if a rather large website was to use this (Pipe dream) and was displaying an unregistered version sign or a "BBSDown" sign and had the chance to eliminate that by purchasing, odds are if they like it they will purchase it.
But having undertaken this I've had some second thoughts, the nag screen is probably enough - but this STILL looks like it would be fun to do to all of my pictures in my My Pictures (That would equate to about 8000)....
Scott Turchin
MCSE, MCP+I http://www.tngbbs.com
---------------------- True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi
Scott,
I'm sorry I misunderstood what you were meaning.
For adding text on the bitmap, you can use the free ImageMagick. With that, you can do just about any kind of programmatic modifications to images, including adding text / watermarks.
Getting somewhere with this GDIPLUS drawing text on a picture, but it is ignoring the position (bounding rectangle in GDIPdrawstring), and only the last 3 chars are drawn on the image... Once again, I must put it down, this time to work on something else - Any GDIP experts out there?
Code:
' A very simple application which displays a picture file chosen by the user.
' Uses GDIPLUS and includes error reporting using GDIplus status codes
' PB Win 8.04, no dependencies except standard INCLUDES.
'
' Chris Holbrook 1 August 2008
'
' 5-AUG-2007 revised WM_ERASEBKGND handler
' 21-OCT-2008 added code to write a fixed string to the image.
' the code is all in the WM_INITDIALOG and WM_ERASEBKGND
' handlers in the PICDLGCB function
'
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC"
#INCLUDE "comdlg32.inc"
#INCLUDE "c:\bepo\sgoti\GDIPLUS.INC"
' GDI+ status (error) codes
%StatusOk = 0
%StatusGenericError = 1
%StatusInvalidParameter = 2
%StatusOutOfMemory = 3
%StatusObjectBusy = 4
%StatusInsufficientBuffer = 5
%StatusNotImplemented = 6
%StatusWin32Error = 7
%StatusWrongState = 8
%StatusAborted = 9
%StatusFileNotFound = 10
%StatusValueOverflow = 11
%StatusAccessDenied = 12
%StatusUnknownImageFormat = 13
%StatusFontFamilyNotFound = 14
%StatusFontStyleNotFound = 15
%StatusNotTrueTypeFont = 16
%StatusUnsupportedGdiplusVersion = 17
%StatusGdiplusNotInitialized = 18
%StatusPropertyNotFound = 19
%StatusPropertyNotSupported = 20
%IDD_DIALOG1 = 101
%IDC_getpic_bn = 1004
'------------------------------------------------------------------------------
DECLARE SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG, _ picture dimensions
BYVAL xCell AS LONG, BYVAL yCell AS LONG, _ FRAME dimensions
BYREF xOfs AS LONG, BYREF yOfs AS LONG, _ calc'd offset in frame
BYREF xSize AS LONG, BYREF ySize AS LONG) ' thumbnail dimensions
'-------------------------------------------------------------------------------------------------------
' Computes location and size to stretch a bitmap preserving its aspect.
'
SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG, _ picture dimensions
BYVAL xCell AS LONG, BYVAL yCell AS LONG, _ FRAME dimensions
BYREF xOfs AS LONG, BYREF yOfs AS LONG, _ calc'd offset in frame
BYREF xSize AS LONG, BYREF ySize AS LONG) EXPORT ' thumbnail dimensions
LOCAL SCALE AS SINGLE
IF xPIC& THEN scale! = xCell& / xPic&
IF scale! > 1 THEN scale! = 1
xSize& = xPic& * scale!: ySize& = yPic& * scale!
' In case Height > 150 compute new scale factor
IF ySize& > yCell& THEN
IF yPic& THEN scale! = yCell& / yPic&
xSize& = xPic& * scale!: ySize& = yPic& * scale!
END IF
xOfs& = (xCell& - xSize&) \ 2
yOfs& = (yCell& - ySize&) \ 2
END SUB
'---------------------------------------------------------------------
' get image filename
FUNCTION getpic (hD AS LONG) AS STRING
LOCAL buf, spath, sfile AS STRING
LOCAL dwstyle AS DWORD
LOCAL hFile AS LONG
dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
Buf = "Picture files (*.JPG,*.PNG,*.TIF,*.ICO,*.GIF,*.BMP)|*.JPG|*.PNG|*.TIF|*.ICO|*.PNG|*.BMP|"
sfile = "*.JPG;*.PNG;*.TIF;*.ICO;*.GIF;*.BMP"
IF OpenFileDialog (hD, "Locate image file ", sfile, spath, buf, "JPG", dwstyle) = 0 THEN
EXIT FUNCTION
END IF
FUNCTION = sfile
END FUNCTION
'----------------------------------------------------------------------
FUNCTION MakeFont(BYVAL fName AS STRING, BYVAL ptSize AS LONG, _
OPT BYVAL attr AS STRING) AS DWORD
'--------------------------------------------------------------------
' Create a desired font and return its handle.
' attr = "biu" for bold, italic, and underlined (any order)
'--------------------------------------------------------------------
LOCAL hDC AS DWORD, CharSet AS LONG, CyPixels AS LONG
LOCAL BOLD, italic, uLine AS LONG
IF LEN(attr) THEN
IF INSTR(LCASE$(attr), "b") THEN BOLD = %FW_BOLD
IF INSTR(LCASE$(attr), "i") THEN italic = 1
IF INSTR(LCASE$(attr), "u") THEN uLine = 1
END IF
hDC = GetDC(%HWND_DESKTOP)
CyPixels = GetDeviceCaps(hDC, %LOGPIXELSY)
ReleaseDC %HWND_DESKTOP, hDC
PtSize = 0 - (ptSize * CyPixels) \ 72
FUNCTION = CreateFont(ptSize, 0, 0, 0, BOLD, italic, uLine, _
%FALSE, CharSet, %OUT_TT_PRECIS, _
%CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _
%FF_DONTCARE , BYCOPY fName)
END FUNCTION
'------------------------------------------------------------------------
' callback function for dialog on which the image is displayed
'
CALLBACK FUNCTION PicDlgCB()
STATIC sPicPath AS STRING
STATIC himage AS DWORD
LOCAL pGraphics AS DWORD
LOCAL hdc AS DWORD
STATIC pfont, pfontfamily, pbrush, pformat _
AS DWORD
LOCAL r AS rect
LOCAL lPixelFormat AS LONG
LOCAL l, framex, framey AS LONG
STATIC ofsx, ofsy, tX, tY AS LONG
LOCAL maxwidth, maxheight AS LONG
LOCAL origwidth, origheight AS SINGLE
STATIC sGDIPStatusCodes() AS STRING ' table of error codes referenced by GDIP status codes
LOCAL sGDIPfn AS STRING ' GDIP function name for error reporting
LOCAL sz AS ASCIZ * 16
LOCAL sfont AS STRING
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' initialise static variables
himage = 0: ofsx = 0: ofsy = 0: tX = 0: tY = 0
' create font
'hfont = makefont ("Courier New", 10, "")
'Create Brush and Pen
GdipCreateSolidFill(&HFF000000, pBrush)
'Create FontFamily, Font and Format
sfont = UCODE$("Courier New")
L = GdipCreateFontFamilyFromName(BYVAL sfont, BYVAL %NULL, pFontFamily)
'IF l THEN sGDIPfn = "GdipCreateFontFamilyFromName": GOSUB gdiperror
L = GdipCreateFont(pFontFamily, 20, %FontStyleBold, %UnitPixel, pFont)
L = GdipCreateStringFormat(BYVAL %NULL, BYVAL %LANG_NEUTRAL, BYVAL VARPTR( pFormat))
L = GdipSetStringFormatLineAlign(pFormat, %StringAlignmentCenter)
L = GdipSetStringFormatAlign(pFormat, %StringAlignmentCenter)
L = GdipSetStringFormatFlags(pFormat, %StringFormatFlagsNoClip OR %StringFormatFlagsNoWrap)
L = GdipSetStringFormatTrimming(pFormat, %StringTrimmingNone)
' load GDIPlus error messages
GOSUB LoadGDIPERMS
'
CASE %WM_ERASEBKGND
IF himage = 0 THEN FUNCTION = 0 : EXIT SELECT
hdc = getdc(CBHNDL)
IF GdipCreatefromHDC ( hDC, pGraphics) = 0 THEN
l = GdipDrawImageRectI(pGraphics, himage, ofsX, ofsY, tX, tY)
IF l THEN sGDIPfn = "GdipDrawImageRectI": GOSUB gdiperror
END IF
sz = UCODE$("hello!")
getclientrect CBHNDL, BYVAL VARPTR(r)
r.nleft = 10: r.ntop = 10
l = GdipDrawString ( pgraphics, sz, 6, pfont, r, pFormat, pBrush)
l = gdipdeletegraphics(pgraphics)
IF l THEN sGDIPfn = "gdipdeletegraphics": GOSUB gdiperror
FUNCTION = 1
'
CASE %WM_USER + 401
spicpath = UCODE$(GetPic(CBHNDL))
getClientrect(CBHNDL, r)
IF himage THEN gdipdisposeimage (himage)
l = GDIPLoadImageFromFile (BYVAL spicPath , BYREF hImage)
IF l THEN sGDIPfn = "GDIPLoadImageFromFile": GOSUB gdiperror
IF hImage = 0 THEN EXIT SELECT
' get image height, width & pixel format
l = GdipGetImageDimension (BYVAL hImage, BYREF origwidth, BYREF origheight)
IF l THEN sGDIPfn = "GdipGetImageDimension": GOSUB gdiperror
maxwidth = r.nright - r.nleft : maxheight = r.nbottom - r.ntop
l = GdipGetImagePixelFormat (BYVAL hImage, BYREF lPixelFormat)
IF l THEN sGDIPfn = "GdipGetImagePixelFormat": GOSUB gdiperror
' derive new image size for display on the dailog, preserving aspect ratio
' the results are declared STATIC so that the %WM_ERASEBKGND handler can use them
skIconise ( BYVAL origwidth, BYVAL origheight, BYVAL maxwidth, BYVAL maxheight, _
BYREF ofsX, BYREF ofsY, BYREF tX, BYREF tY)
' force redraw via WM_ERASEBKGND
invalidaterect CBHNDL, r, %TRUE
'
CASE %WM_DESTROY
IF himage THEN
'Cleanup brush
IF (pBrush) THEN
GdipDeleteBrush(pBrush)
pBrush = %NULL
END IF
'Cleanup font
IF (pFont) THEN
GdipDeleteFont(pFont)
pFont = %NULL
END IF
'Cleanup format
IF (pFormat) THEN
GdipDeleteStringFormat(pFormat)
pFormat = %NULL
END IF
'Cleanup font family
IF (pFontFamily) THEN
GdipDeleteFontFamily(pFontFamily)
END IF
l = gdipdisposeimage(himage)
IF l THEN sGDIPfn = "GdipDisposeImage": GOSUB gdiperror
END IF
'
END SELECT
EXIT FUNCTION
''''''''''''''''''''''
gdiperror:
? sGDIPfn + ":" + sGDIPStatusCodes(l)
EXIT FUNCTION
RETURN
''''''''''''''''''''''
LoadGDIPERMS:
DIM sGDIPStatusCodes(0 TO 20) AS STATIC STRING
sGDIPStatusCodes(%StatusOk ) = "Ok
sGDIPStatusCodes(%StatusGenericError ) = "Generic Error
sGDIPStatusCodes(%StatusInvalidParameter ) = "Invalid Parameter
sGDIPStatusCodes(%StatusOutOfMemory ) = "Out Of Memory
sGDIPStatusCodes(%StatusObjectBusy ) = "Object Busy
sGDIPStatusCodes(%StatusInsufficientBuffer ) = "Insufficient Buffer
sGDIPStatusCodes(%StatusNotImplemented ) = "Not Implemented
sGDIPStatusCodes(%StatusWin32Error ) = "Win32 Error
sGDIPStatusCodes(%StatusWrongState ) = "Wrong State
sGDIPStatusCodes(%StatusAborted ) = "Aborted
sGDIPStatusCodes(%StatusFileNotFound ) = "File Not Found
sGDIPStatusCodes(%StatusValueOverflow ) = "Value Overflow
sGDIPStatusCodes(%StatusAccessDenied ) = "Access Denied
sGDIPStatusCodes(%StatusUnknownImageFormat ) = "Unknown Image Format
sGDIPStatusCodes(%StatusFontFamilyNotFound ) = "Font Family Not Found
sGDIPStatusCodes(%StatusFontStyleNotFound ) = "Font Style Not Found
sGDIPStatusCodes(%StatusNotTrueTypeFont ) = "Not TrueType Font
sGDIPStatusCodes(%StatusUnsupportedGdiplusVersion ) = "Unsupported Gdiplus Version
sGDIPStatusCodes(%StatusGdiplusNotInitialized ) = "Gdiplus Not Initialized
sGDIPStatusCodes(%StatusPropertyNotFound ) = "Property Not Found
sGDIPStatusCodes(%StatusPropertyNotSupported ) = "Property Not Supported
RETURN
END FUNCTION
'------------------------------------------------------------------------
' main dialog callback function
'
CALLBACK FUNCTION MainDlgCB()
LOCAL s AS STRING
STATIC hPicWnd AS DWORD
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' create another dialog on which the image will be displayed.
' It didn't have to be a dialog, but if a control in the main dialog
' was used then it would have to be sub- or super-classed to receive its
' own WM_ERASEBKGND messages. This is just the easiest (DDT) way to do it.
DIALOG NEW CBHNDL, "", 85, 5, 190, 125, %WS_POPUP OR %WS_BORDER OR _
%WS_POPUP OR %WS_CHILD OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
%DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
%WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hPicWnd
DIALOG SHOW MODELESS hPicWnd, CALL PicDlgCB 'TO lRslt
CASE %WM_COMMAND
SELECT CASE AS LONG CBCTL
CASE %IDC_getpic_bn
IF HI(WORD,CBWPARAM) = %BN_CLICKED THEN
sendmessage hPicWnd, %WM_USER + 401, 0, 0
END IF
END SELECT
END SELECT
END FUNCTION
'------------------------------------------------------------------
FUNCTION MainDlg(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG
LOCAL hDlg AS DWORD
DIALOG NEW hParent, "using GDI+ example 1", 139, 129, 279, 135, _
%WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
%DS_NOFAILCREATE OR %DS_SETFONT, _
%WS_EX_CONTROLPARENT, TO hDlg
CONTROL ADD BUTTON, hDlg, %IDC_getpic_bn, "find a picture", 5, 5, 75, 15
DIALOG SHOW MODAL hDlg, CALL MainDlgCB TO lRslt
FUNCTION = lRslt
END FUNCTION
'=======================================================================
FUNCTION PBMAIN()
STATIC nstatus AS LONG
STATIC token AS DWORD
STATIC StartupInput AS GdiplusStartupInput
StartupInput.GdiplusVersion = 1
nStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
IF nStatus THEN
MSGBOX "Error initializing GDI+", %MB_APPLMODAL, "Warning"
EXIT FUNCTION
END IF
MainDlg %HWND_DESKTOP
GdiplusShutdown token
END FUNCTION
Just use the powerbasic internal functions. In most cases they really should be all what you need to make something like a simple watermark. (I don't think that it supports something like alpha channels yet?)The only problem is the jpg converting. For this problem I use the freeimage.dll (and somewhere here in the forum are some declarations and includes for it...but don't have time to look for them.)
After loading the image with freeimage the most work should be done -> just load the jpg with freeimage, convert it to bitmap, and use the handle to manipulate it with the PowerBasic-GRAPHIC statements.
If the passing by handle doesn't work, you possibly can load the jpg, and save it per freeimage.dll as bmp to load it with powerbasic statements directly from harddisk. I am no expert, but this would be my way to try.
At the third attempt, here is text drawn on an image with GDI+. I still don't understand how to position the text on the image, it has to do with the stringformat setup.
Having drawn text over the image, you could save the resulting graphic to a file if you wanted, so this example could easily be adapted to label an image file, or batch of image files, with text.
Code:
' A very simple application which displays a picture file chosen by the user.
' Uses GDIPLUS and includes error reporting using GDIplus status codes
' PB Win 8.04, no dependencies except standard INCLUDES.
'
' Chris Holbrook 1 August 2008
'
' 23-OCT-2007 added code to draw a text string on the image
'
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC"
#INCLUDE "comdlg32.inc"
#INCLUDE "GDIPLUS.INC"
' GDI+ status (error) codes
%StatusOk = 0
%StatusGenericError = 1
%StatusInvalidParameter = 2
%StatusOutOfMemory = 3
%StatusObjectBusy = 4
%StatusInsufficientBuffer = 5
%StatusNotImplemented = 6
%StatusWin32Error = 7
%StatusWrongState = 8
%StatusAborted = 9
%StatusFileNotFound = 10
%StatusValueOverflow = 11
%StatusAccessDenied = 12
%StatusUnknownImageFormat = 13
%StatusFontFamilyNotFound = 14
%StatusFontStyleNotFound = 15
%StatusNotTrueTypeFont = 16
%StatusUnsupportedGdiplusVersion = 17
%StatusGdiplusNotInitialized = 18
%StatusPropertyNotFound = 19
%StatusPropertyNotSupported = 20
%IDD_DIALOG1 = 101
%IDC_getpic_bn = 1004
'------------------------------------------------------------------------------
DECLARE SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG, _ picture dimensions
BYVAL xCell AS LONG, BYVAL yCell AS LONG, _ FRAME dimensions
BYREF xOfs AS LONG, BYREF yOfs AS LONG, _ calc'd offset in frame
BYREF xSize AS LONG, BYREF ySize AS LONG) ' thumbnail dimensions
'-------------------------------------------------------------------------------------------------------
' Computes location and size to stretch a bitmap preserving its aspect.
'
SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG, _ picture dimensions
BYVAL xCell AS LONG, BYVAL yCell AS LONG, _ FRAME dimensions
BYREF xOfs AS LONG, BYREF yOfs AS LONG, _ calc'd offset in frame
BYREF xSize AS LONG, BYREF ySize AS LONG) EXPORT ' thumbnail dimensions
LOCAL SCALE AS SINGLE
IF xPIC& THEN scale! = xCell& / xPic&
IF scale! > 1 THEN scale! = 1
xSize& = xPic& * scale!: ySize& = yPic& * scale!
' In case Height > 150 compute new scale factor
IF ySize& > yCell& THEN
IF yPic& THEN scale! = yCell& / yPic&
xSize& = xPic& * scale!: ySize& = yPic& * scale!
END IF
xOfs& = (xCell& - xSize&) \ 2
yOfs& = (yCell& - ySize&) \ 2
END SUB
'---------------------------------------------------------------------
' get image filename
FUNCTION getpic (hD AS LONG) AS STRING
LOCAL buf, spath, sfile AS STRING
LOCAL dwstyle AS DWORD
LOCAL hFile AS LONG
dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
Buf = "Picture files (*.JPG,*.PNG,*.TIF,*.ICO,*.GIF,*.BMP)|*.JPG|*.PNG|*.TIF|*.ICO|*.PNG|*.BMP|"
sfile = "*.JPG;*.PNG;*.TIF;*.ICO;*.GIF;*.BMP"
IF OpenFileDialog (hD, "Locate image file ", sfile, spath, buf, "JPG", dwstyle) = 0 THEN
EXIT FUNCTION
END IF
FUNCTION = sfile
END FUNCTION
'----------------------------------------------------------------------
FUNCTION MakeFont(BYVAL fName AS STRING, BYVAL ptSize AS LONG, _
OPT BYVAL attr AS STRING) AS DWORD
'--------------------------------------------------------------------
' Create a desired font and return its handle.
' attr = "biu" for bold, italic, and underlined (any order)
'--------------------------------------------------------------------
LOCAL hDC AS DWORD, CharSet AS LONG, CyPixels AS LONG
LOCAL BOLD, italic, uLine AS LONG
IF LEN(attr) THEN
IF INSTR(LCASE$(attr), "b") THEN BOLD = %FW_BOLD
IF INSTR(LCASE$(attr), "i") THEN italic = 1
IF INSTR(LCASE$(attr), "u") THEN uLine = 1
END IF
hDC = GetDC(%HWND_DESKTOP)
CyPixels = GetDeviceCaps(hDC, %LOGPIXELSY)
ReleaseDC %HWND_DESKTOP, hDC
PtSize = 0 - (ptSize * CyPixels) \ 72
FUNCTION = CreateFont(ptSize, 0, 0, 0, BOLD, italic, uLine, _
%FALSE, CharSet, %OUT_TT_PRECIS, _
%CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _
%FF_DONTCARE , BYCOPY fName)
END FUNCTION
'------------------------------------------------------------------------
' callback function for dialog on which the image is displayed
'
CALLBACK FUNCTION PicDlgCB()
STATIC sPicPath AS STRING
STATIC himage AS DWORD
LOCAL pGraphics AS DWORD
LOCAL hdc AS DWORD
STATIC pfont, pfontfamily, pbrush, pformat _
AS DWORD
LOCAL r AS rect
LOCAL lPixelFormat AS LONG
LOCAL l, framex, framey AS LONG
STATIC ofsx, ofsy, tX, tY AS LONG
LOCAL maxwidth, maxheight AS LONG
LOCAL origwidth, origheight AS SINGLE
STATIC sGDIPStatusCodes() AS STRING ' table of error codes referenced by GDIP status codes
LOCAL sGDIPfn AS STRING ' GDIP function name for error reporting
LOCAL sz AS ASCIZ * 16
LOCAL s, sfont AS STRING
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' initialise static variables
himage = 0: ofsx = 0: ofsy = 0: tX = 0: tY = 0
' create font
'hfont = makefont ("Courier New", 10, "")
'Create Brush and Pen
GdipCreateSolidFill(&HFF000000, pBrush)
'Create FontFamily, Font and Format
sfont = UCODE$("Courier New")
L = GdipCreateFontFamilyFromName(BYVAL sfont, BYVAL %NULL, pFontFamily)
'IF l THEN sGDIPfn = "GdipCreateFontFamilyFromName": GOSUB gdiperror
L = GdipCreateFont(pFontFamily, 20, %FontStyleBold, %UnitPixel, pFont)
L = GdipCreateStringFormat(BYVAL %NULL, BYVAL %LANG_NEUTRAL, BYVAL VARPTR( pFormat))
' L = GdipSetStringFormatLineAlign(pFormat, %StringAlignmentCenter)
' L = GdipSetStringFormatAlign(pFormat, %StringAlignmentCenter)
L = GdipSetStringFormatFlags(pFormat, %StringFormatFlagsNoClip OR %StringFormatFlagsNoWrap)
L = GdipSetStringFormatTrimming(pFormat, %StringTrimmingNone)
' load GDIPlus error messages
GOSUB LoadGDIPERMS
'
CASE %WM_ERASEBKGND
IF himage = 0 THEN FUNCTION = 0 : EXIT SELECT
hdc = getdc(CBHNDL)
IF GdipCreatefromHDC ( hDC, pGraphics) = 0 THEN
l = GdipDrawImageRectI(pGraphics, himage, ofsX, ofsY, tX, tY)
IF l THEN sGDIPfn = "GdipDrawImageRectI": GOSUB gdiperror
END IF
s = "UNLICENSED COPY"
l = LEN(s)
s = UCODE$(s)
'getclientrect CBHNDL, BYVAL VARPTR(r)
setrect r, 50, 50, 100, 100
l = GdipDrawString ( pgraphics, s, l, pfont, r, pFormat, pBrush)
l = gdipdeletegraphics(pgraphics)
IF l THEN sGDIPfn = "gdipdeletegraphics": GOSUB gdiperror
FUNCTION = 1
'
CASE %WM_USER + 401
spicpath = UCODE$(GetPic(CBHNDL))
getClientrect(CBHNDL, r)
IF himage THEN gdipdisposeimage (himage)
l = GDIPLoadImageFromFile (BYVAL spicPath , BYREF hImage)
IF l THEN sGDIPfn = "GDIPLoadImageFromFile": GOSUB gdiperror
IF hImage = 0 THEN EXIT SELECT
' get image height, width & pixel format
l = GdipGetImageDimension (BYVAL hImage, BYREF origwidth, BYREF origheight)
IF l THEN sGDIPfn = "GdipGetImageDimension": GOSUB gdiperror
maxwidth = r.nright - r.nleft : maxheight = r.nbottom - r.ntop
l = GdipGetImagePixelFormat (BYVAL hImage, BYREF lPixelFormat)
IF l THEN sGDIPfn = "GdipGetImagePixelFormat": GOSUB gdiperror
' derive new image size for display on the dailog, preserving aspect ratio
' the results are declared STATIC so that the %WM_ERASEBKGND handler can use them
skIconise ( BYVAL origwidth, BYVAL origheight, BYVAL maxwidth, BYVAL maxheight, _
BYREF ofsX, BYREF ofsY, BYREF tX, BYREF tY)
' force redraw via WM_ERASEBKGND
invalidaterect CBHNDL, r, %TRUE
'
CASE %WM_DESTROY
IF himage THEN
'Cleanup brush
IF (pBrush) THEN
GdipDeleteBrush(pBrush)
pBrush = %NULL
END IF
'Cleanup font
IF (pFont) THEN
GdipDeleteFont(pFont)
pFont = %NULL
END IF
'Cleanup format
IF (pFormat) THEN
GdipDeleteStringFormat(pFormat)
pFormat = %NULL
END IF
'Cleanup font family
IF (pFontFamily) THEN
GdipDeleteFontFamily(pFontFamily)
END IF
l = gdipdisposeimage(himage)
IF l THEN sGDIPfn = "GdipDisposeImage": GOSUB gdiperror
END IF
'
END SELECT
EXIT FUNCTION
''''''''''''''''''''''
gdiperror:
? sGDIPfn + ":" + sGDIPStatusCodes(l)
EXIT FUNCTION
RETURN
''''''''''''''''''''''
LoadGDIPERMS:
DIM sGDIPStatusCodes(0 TO 20) AS STATIC STRING
sGDIPStatusCodes(%StatusOk ) = "Ok
sGDIPStatusCodes(%StatusGenericError ) = "Generic Error
sGDIPStatusCodes(%StatusInvalidParameter ) = "Invalid Parameter
sGDIPStatusCodes(%StatusOutOfMemory ) = "Out Of Memory
sGDIPStatusCodes(%StatusObjectBusy ) = "Object Busy
sGDIPStatusCodes(%StatusInsufficientBuffer ) = "Insufficient Buffer
sGDIPStatusCodes(%StatusNotImplemented ) = "Not Implemented
sGDIPStatusCodes(%StatusWin32Error ) = "Win32 Error
sGDIPStatusCodes(%StatusWrongState ) = "Wrong State
sGDIPStatusCodes(%StatusAborted ) = "Aborted
sGDIPStatusCodes(%StatusFileNotFound ) = "File Not Found
sGDIPStatusCodes(%StatusValueOverflow ) = "Value Overflow
sGDIPStatusCodes(%StatusAccessDenied ) = "Access Denied
sGDIPStatusCodes(%StatusUnknownImageFormat ) = "Unknown Image Format
sGDIPStatusCodes(%StatusFontFamilyNotFound ) = "Font Family Not Found
sGDIPStatusCodes(%StatusFontStyleNotFound ) = "Font Style Not Found
sGDIPStatusCodes(%StatusNotTrueTypeFont ) = "Not TrueType Font
sGDIPStatusCodes(%StatusUnsupportedGdiplusVersion ) = "Unsupported Gdiplus Version
sGDIPStatusCodes(%StatusGdiplusNotInitialized ) = "Gdiplus Not Initialized
sGDIPStatusCodes(%StatusPropertyNotFound ) = "Property Not Found
sGDIPStatusCodes(%StatusPropertyNotSupported ) = "Property Not Supported
RETURN
END FUNCTION
'------------------------------------------------------------------------
' main dialog callback function
'
CALLBACK FUNCTION MainDlgCB()
LOCAL s AS STRING
STATIC hPicWnd AS DWORD
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' create another dialog on which the image will be displayed.
' It didn't have to be a dialog, but if a control in the main dialog
' was used then it would have to be sub- or super-classed to receive its
' own WM_ERASEBKGND messages. This is just the easiest (DDT) way to do it.
DIALOG NEW CBHNDL, "", 85, 5, 190, 125, %WS_POPUP OR %WS_BORDER OR _
%WS_POPUP OR %WS_CHILD OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
%DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
%WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hPicWnd
DIALOG SHOW MODELESS hPicWnd, CALL PicDlgCB 'TO lRslt
CASE %WM_COMMAND
SELECT CASE AS LONG CBCTL
CASE %IDC_getpic_bn
IF HI(WORD,CBWPARAM) = %BN_CLICKED THEN
sendmessage hPicWnd, %WM_USER + 401, 0, 0
END IF
END SELECT
END SELECT
END FUNCTION
'------------------------------------------------------------------
FUNCTION MainDlg(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG
LOCAL hDlg AS DWORD
DIALOG NEW hParent, "using GDI+ to draw text on image", 139, 129, 279, 135, _
%WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
%DS_NOFAILCREATE OR %DS_SETFONT, _
%WS_EX_CONTROLPARENT, TO hDlg
CONTROL ADD BUTTON, hDlg, %IDC_getpic_bn, "find a picture", 5, 5, 75, 15
DIALOG SHOW MODAL hDlg, CALL MainDlgCB TO lRslt
FUNCTION = lRslt
END FUNCTION
'=======================================================================
FUNCTION PBMAIN()
STATIC nstatus AS LONG
STATIC token AS DWORD
STATIC StartupInput AS GdiplusStartupInput
StartupInput.GdiplusVersion = 1
nStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
IF nStatus THEN
MSGBOX "Error initializing GDI+", %MB_APPLMODAL, "Warning"
EXIT FUNCTION
END IF
MainDlg %HWND_DESKTOP
GdiplusShutdown token
END FUNCTION
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment