661 lines
16 KiB
Text
661 lines
16 KiB
Text
VERSION DVX 1.00
|
|
Begin Form IconEd
|
|
Caption = "DVX Icon Editor"
|
|
Layout = VBox
|
|
AutoSize = True
|
|
Resizable = False
|
|
Centered = True
|
|
|
|
Begin Menu mnuFile
|
|
Caption = "&File"
|
|
Begin Menu mnuNew
|
|
Caption = "&New"
|
|
End
|
|
Begin Menu mnuOpen
|
|
Caption = "&Open..."
|
|
End
|
|
Begin Menu mnuSave
|
|
Caption = "&Save..."
|
|
End
|
|
Begin Menu mnuPrint
|
|
Caption = "&Print..."
|
|
End
|
|
Begin Menu mnuSep1
|
|
Caption = "-"
|
|
End
|
|
Begin Menu mnuExit
|
|
Caption = "E&xit"
|
|
End
|
|
End
|
|
|
|
Begin Menu mnuTools
|
|
Caption = "&Tools"
|
|
Begin Menu mnuPencil
|
|
Caption = "&Pencil"
|
|
Checked = True
|
|
RadioCheck = True
|
|
End
|
|
Begin Menu mnuEraser
|
|
Caption = "&Eraser"
|
|
RadioCheck = True
|
|
End
|
|
Begin Menu mnuPicker
|
|
Caption = "Color Pic&ker"
|
|
RadioCheck = True
|
|
End
|
|
End
|
|
|
|
Begin Menu mnuSize
|
|
Caption = "&Size"
|
|
Begin Menu mnuSize16
|
|
Caption = "16 x 16"
|
|
RadioCheck = True
|
|
End
|
|
Begin Menu mnuSize24
|
|
Caption = "24 x 24"
|
|
RadioCheck = True
|
|
End
|
|
Begin Menu mnuSize32
|
|
Caption = "32 x 32"
|
|
Checked = True
|
|
RadioCheck = True
|
|
End
|
|
End
|
|
Begin Menu mnuHelp
|
|
Caption = "&Help"
|
|
Begin Menu mnuHelpContents
|
|
Caption = "&Contents"
|
|
End
|
|
Begin Menu mnuHelpSep
|
|
Caption = "-"
|
|
End
|
|
Begin Menu mnuAbout
|
|
Caption = "&About Icon Editor..."
|
|
End
|
|
End
|
|
|
|
Begin Frame fraMain
|
|
Caption = ""
|
|
Layout = HBox
|
|
Weight = 100
|
|
|
|
Begin PictureBox cvEditor
|
|
Width = 256
|
|
Height = 256
|
|
Weight = 0
|
|
End
|
|
|
|
Begin Frame fraSidebar
|
|
Caption = ""
|
|
Layout = VBox
|
|
Width = 100
|
|
Weight = 0
|
|
|
|
Begin Label lblPreview
|
|
Caption = "Preview:"
|
|
End
|
|
|
|
Begin PictureBox cvPreview
|
|
Width = 32
|
|
Height = 32
|
|
Weight = 0
|
|
End
|
|
|
|
Begin Label lblColor
|
|
Caption = "Color:"
|
|
End
|
|
|
|
Begin PictureBox cvSelColor
|
|
Width = 32
|
|
Height = 20
|
|
Weight = 0
|
|
End
|
|
|
|
Begin Label lblPalette
|
|
Caption = "Palette:"
|
|
End
|
|
|
|
Begin PictureBox cvPalette
|
|
Width = 80
|
|
Height = 80
|
|
Weight = 0
|
|
End
|
|
End
|
|
End
|
|
|
|
Begin Label lblStatus
|
|
Caption = "Ready. (0, 0)"
|
|
Height = 16
|
|
Weight = 0
|
|
End
|
|
End
|
|
|
|
' The MIT License (MIT)
|
|
'
|
|
' Copyright (C) 2026 Scott Duensing
|
|
'
|
|
' Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
' of this software and associated documentation files (the "Software"), to
|
|
' deal in the Software without restriction, including without limitation the
|
|
' rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
' sell copies of the Software, and to permit persons to whom the Software is
|
|
' furnished to do so, subject to the following conditions:
|
|
'
|
|
' The above copyright notice and this permission notice shall be included in
|
|
' all copies or substantial portions of the Software.
|
|
'
|
|
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
' FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
' IN THE SOFTWARE.
|
|
|
|
|
|
OPTION EXPLICIT
|
|
|
|
|
|
' Pixels are held in pixels() at their exact RGB values. The preview
|
|
' canvas (used for Load and Save) stores the display's pixel format, so
|
|
' in 15/16-bit and 256-color display modes colors are rounded to what the
|
|
' display can show when an icon is opened or saved.
|
|
|
|
CONST CANVAS_SIZE = 256
|
|
CONST BG_COLOR = &H00C0C0C0
|
|
CONST GRID_COLOR = &H00808080
|
|
CONST EDGE_COLOR = &H00404040
|
|
CONST TOOL_PENCIL = 0
|
|
CONST TOOL_ERASER = 1
|
|
CONST TOOL_PICKER = 2
|
|
CONST PAL_COLS = 8
|
|
CONST PAL_ROWS = 4
|
|
CONST PAL_COUNT = 32 ' PAL_COLS * PAL_ROWS (CONST takes only literals)
|
|
CONST PAL_CELL = 10
|
|
CONST SIZE_SMALL = 16
|
|
CONST SIZE_MEDIUM = 24
|
|
CONST MAX_ICON = 32
|
|
CONST HELP_FILE = "iconed.hlp"
|
|
CONST OPEN_FILTER = "Icon Images (*.bmp;*.png)|All Files (*.*)"
|
|
CONST SAVE_FILTER = "PNG Images (*.png)|All Files (*.*)"
|
|
|
|
DIM SHARED pixels(MAX_ICON - 1, MAX_ICON - 1) AS LONG
|
|
DIM SHARED palette(PAL_COUNT - 1) AS LONG
|
|
DIM SHARED iconW AS INTEGER
|
|
DIM SHARED iconH AS INTEGER
|
|
DIM SHARED pixelSize AS INTEGER
|
|
DIM SHARED curTool AS INTEGER
|
|
DIM SHARED curColor AS LONG
|
|
DIM SHARED drawing AS BOOLEAN
|
|
DIM SHARED dirty AS BOOLEAN
|
|
DIM SHARED filePath AS STRING
|
|
|
|
|
|
SUB InitPalette
|
|
palette(0) = &H00000000
|
|
palette(1) = &H00FFFFFF
|
|
palette(2) = &H00C0C0C0
|
|
palette(3) = &H00808080
|
|
palette(4) = &H000000FF
|
|
palette(5) = &H00000080
|
|
palette(6) = &H000080FF
|
|
palette(7) = &H00004080
|
|
palette(8) = &H0000FFFF
|
|
palette(9) = &H00008080
|
|
palette(10) = &H0000FF00
|
|
palette(11) = &H00008000
|
|
palette(12) = &H00FFFF00
|
|
palette(13) = &H00808000
|
|
palette(14) = &H0080FF00
|
|
palette(15) = &H00404000
|
|
palette(16) = &H00FF0000
|
|
palette(17) = &H00800000
|
|
palette(18) = &H00FF0080
|
|
palette(19) = &H00800080
|
|
palette(20) = &H00FF00FF
|
|
palette(21) = &H008000FF
|
|
palette(22) = &H00C080FF
|
|
palette(23) = &H00FF4040
|
|
palette(24) = &H00404040
|
|
palette(25) = &H00A0A0A0
|
|
palette(26) = &H00E0E0E0
|
|
palette(27) = &H00C0E0FF
|
|
palette(28) = &H00E0FFC0
|
|
palette(29) = &H00FFE0C0
|
|
palette(30) = &H00C0C0FF
|
|
palette(31) = &H00FFC0C0
|
|
END SUB
|
|
|
|
|
|
SUB ClearPixels
|
|
DIM x AS INTEGER
|
|
DIM y AS INTEGER
|
|
FOR y = 0 TO MAX_ICON - 1
|
|
FOR x = 0 TO MAX_ICON - 1
|
|
pixels(x, y) = BG_COLOR
|
|
NEXT x
|
|
NEXT y
|
|
dirty = False
|
|
END SUB
|
|
|
|
|
|
' The preview canvas always matches the icon size, so Save writes exactly
|
|
' iconW x iconH pixels.
|
|
SUB SetIconSize(w AS INTEGER)
|
|
iconW = w
|
|
iconH = w
|
|
pixelSize = CANVAS_SIZE \ w
|
|
cvPreview.Resize w, w
|
|
END SUB
|
|
|
|
|
|
' Checks the Size menu item for the current icon size.
|
|
SUB CheckSizeMenu
|
|
IF iconW = SIZE_SMALL THEN
|
|
mnuSize16.Checked = True
|
|
ELSEIF iconW = SIZE_MEDIUM THEN
|
|
mnuSize24.Checked = True
|
|
ELSE
|
|
mnuSize32.Checked = True
|
|
END IF
|
|
END SUB
|
|
|
|
|
|
FUNCTION IsIconSize(w AS INTEGER) AS BOOLEAN
|
|
IsIconSize = (w = SIZE_SMALL OR w = SIZE_MEDIUM OR w = MAX_ICON)
|
|
END FUNCTION
|
|
|
|
|
|
SUB DrawEditorGrid
|
|
DIM x AS INTEGER
|
|
DIM y AS INTEGER
|
|
DIM edgeW AS INTEGER
|
|
cvEditor.Clear BG_COLOR
|
|
FOR y = 0 TO iconH - 1
|
|
FOR x = 0 TO iconW - 1
|
|
cvEditor.FillRect x * pixelSize, y * pixelSize, pixelSize, pixelSize, pixels(x, y)
|
|
NEXT x
|
|
NEXT y
|
|
FOR x = 0 TO iconW
|
|
cvEditor.DrawLine x * pixelSize, 0, x * pixelSize, iconH * pixelSize, GRID_COLOR
|
|
NEXT x
|
|
FOR y = 0 TO iconH
|
|
cvEditor.DrawLine 0, y * pixelSize, iconW * pixelSize, y * pixelSize, GRID_COLOR
|
|
NEXT y
|
|
edgeW = iconW * pixelSize
|
|
cvEditor.DrawRect 0, 0, edgeW, edgeW, EDGE_COLOR
|
|
cvEditor.Refresh
|
|
END SUB
|
|
|
|
|
|
SUB DrawPreview
|
|
DIM x AS INTEGER
|
|
DIM y AS INTEGER
|
|
FOR y = 0 TO iconH - 1
|
|
FOR x = 0 TO iconW - 1
|
|
cvPreview.SetPixel x, y, pixels(x, y)
|
|
NEXT x
|
|
NEXT y
|
|
cvPreview.Refresh
|
|
END SUB
|
|
|
|
|
|
SUB DrawPalette
|
|
DIM i AS INTEGER
|
|
DIM px AS INTEGER
|
|
DIM py AS INTEGER
|
|
cvPalette.Clear BG_COLOR
|
|
FOR i = 0 TO PAL_COUNT - 1
|
|
px = (i MOD PAL_COLS) * PAL_CELL
|
|
py = (i \ PAL_COLS) * PAL_CELL
|
|
cvPalette.FillRect px, py, PAL_CELL, PAL_CELL, palette(i)
|
|
cvPalette.DrawRect px, py, PAL_CELL, PAL_CELL, &H00000000
|
|
NEXT i
|
|
cvPalette.Refresh
|
|
END SUB
|
|
|
|
|
|
SUB DrawSelectedColor
|
|
cvSelColor.Clear curColor
|
|
cvSelColor.Refresh
|
|
END SUB
|
|
|
|
|
|
SUB RefreshAll
|
|
DrawEditorGrid
|
|
DrawPreview
|
|
DrawSelectedColor
|
|
END SUB
|
|
|
|
|
|
SUB UpdateTitle
|
|
DIM t AS STRING
|
|
t = "DVX Icon Editor - " + LTRIM$(STR$(iconW)) + "x" + LTRIM$(STR$(iconH))
|
|
IF filePath <> "" THEN
|
|
t = t + " - " + filePath
|
|
END IF
|
|
IF dirty THEN
|
|
t = t + " *"
|
|
END IF
|
|
IconEd.Caption = t
|
|
END SUB
|
|
|
|
|
|
SUB SetIconPixel(x AS INTEGER, y AS INTEGER)
|
|
DIM c AS LONG
|
|
IF x < 0 OR x >= iconW OR y < 0 OR y >= iconH THEN
|
|
EXIT SUB
|
|
END IF
|
|
IF curTool = TOOL_ERASER THEN
|
|
c = BG_COLOR
|
|
ELSE
|
|
c = curColor
|
|
END IF
|
|
IF pixels(x, y) <> c THEN
|
|
pixels(x, y) = c
|
|
' The caption only changes on the clean-to-dirty transition.
|
|
IF NOT dirty THEN
|
|
dirty = True
|
|
UpdateTitle
|
|
END IF
|
|
cvEditor.FillRect x * pixelSize, y * pixelSize, pixelSize, pixelSize, c
|
|
cvEditor.DrawLine x * pixelSize, y * pixelSize, (x + 1) * pixelSize, y * pixelSize, GRID_COLOR
|
|
cvEditor.DrawLine x * pixelSize, y * pixelSize, x * pixelSize, (y + 1) * pixelSize, GRID_COLOR
|
|
cvEditor.DrawLine (x + 1) * pixelSize, y * pixelSize, (x + 1) * pixelSize, (y + 1) * pixelSize, GRID_COLOR
|
|
cvEditor.DrawLine x * pixelSize, (y + 1) * pixelSize, (x + 1) * pixelSize, (y + 1) * pixelSize, GRID_COLOR
|
|
cvPreview.SetPixel x, y, c
|
|
END IF
|
|
END SUB
|
|
|
|
|
|
SUB SelectTool(t AS INTEGER)
|
|
curTool = t
|
|
IF t = TOOL_PENCIL THEN
|
|
mnuPencil.Checked = True
|
|
lblStatus.Caption = "Tool: Pencil"
|
|
ELSEIF t = TOOL_ERASER THEN
|
|
mnuEraser.Checked = True
|
|
lblStatus.Caption = "Tool: Eraser"
|
|
ELSEIF t = TOOL_PICKER THEN
|
|
mnuPicker.Checked = True
|
|
lblStatus.Caption = "Tool: Picker"
|
|
END IF
|
|
END SUB
|
|
|
|
|
|
SUB ChangeSize(newSize AS INTEGER)
|
|
DIM ans AS INTEGER
|
|
IF newSize = iconW THEN
|
|
EXIT SUB
|
|
END IF
|
|
IF dirty THEN
|
|
ans = MsgBox("Unsaved changes will be lost. Change size?", vbYesNo)
|
|
IF ans = vbNo THEN
|
|
' The menu already moved the radio check; put it back.
|
|
CheckSizeMenu
|
|
EXIT SUB
|
|
END IF
|
|
END IF
|
|
SetIconSize newSize
|
|
ClearPixels
|
|
filePath = ""
|
|
CheckSizeMenu
|
|
UpdateTitle
|
|
RefreshAll
|
|
lblStatus.Caption = STR$(iconW) + "x" + STR$(iconH) + " - Ready."
|
|
END SUB
|
|
|
|
|
|
' Writes the preview canvas to path. Returns False when the file could
|
|
' not be written.
|
|
FUNCTION SaveIcon(path AS STRING) AS BOOLEAN
|
|
DrawPreview
|
|
SaveIcon = (cvPreview.Save(path) = 0)
|
|
END FUNCTION
|
|
|
|
|
|
SUB IconEd_Load
|
|
InitPalette
|
|
SetIconSize MAX_ICON
|
|
ClearPixels
|
|
curTool = TOOL_PENCIL
|
|
curColor = &H00000000
|
|
drawing = False
|
|
filePath = ""
|
|
DrawPalette
|
|
RefreshAll
|
|
UpdateTitle
|
|
' An icon named on the command line (a document opened from Program
|
|
' Manager or File Manager) is loaded at once.
|
|
IF COMMAND$(1) <> "" THEN
|
|
OpenIcon COMMAND$(1)
|
|
END IF
|
|
END SUB
|
|
|
|
|
|
SUB mnuNew_Click
|
|
DIM ans AS INTEGER
|
|
IF dirty THEN
|
|
ans = MsgBox("Unsaved changes. Start new icon?", vbYesNo)
|
|
IF ans = vbNo THEN
|
|
EXIT SUB
|
|
END IF
|
|
END IF
|
|
ClearPixels
|
|
filePath = ""
|
|
UpdateTitle
|
|
RefreshAll
|
|
END SUB
|
|
|
|
|
|
SUB mnuOpen_Click
|
|
DIM ans AS INTEGER
|
|
DIM path AS STRING
|
|
IF dirty THEN
|
|
ans = MsgBox("Unsaved changes. Open another file?", vbYesNo)
|
|
IF ans = vbNo THEN
|
|
EXIT SUB
|
|
END IF
|
|
END IF
|
|
path = DlgFileOpen$("Open Icon", OPEN_FILTER)
|
|
IF path = "" THEN
|
|
EXIT SUB
|
|
END IF
|
|
OpenIcon path
|
|
END SUB
|
|
|
|
|
|
' Loads the icon in path; a file that is not a 16, 24 or 32 pixel square
|
|
' image is refused (reported) and the current icon stays.
|
|
SUB OpenIcon(path AS STRING)
|
|
DIM w AS INTEGER
|
|
DIM x AS INTEGER
|
|
DIM y AS INTEGER
|
|
' A failed Load leaves the preview unchanged; a successful one gives
|
|
' it the image's size.
|
|
IF cvPreview.Load(path) <> 0 THEN
|
|
MsgBox "Could not load " + path + "."
|
|
EXIT SUB
|
|
END IF
|
|
w = cvPreview.ImageWidth
|
|
IF cvPreview.ImageHeight <> w OR NOT IsIconSize(w) THEN
|
|
' Put the current icon back into the preview.
|
|
cvPreview.Resize iconW, iconH
|
|
DrawPreview
|
|
MsgBox "Icons must be 16 x 16, 24 x 24, or 32 x 32 pixels."
|
|
EXIT SUB
|
|
END IF
|
|
SetIconSize w
|
|
ClearPixels
|
|
FOR y = 0 TO iconH - 1
|
|
FOR x = 0 TO iconW - 1
|
|
pixels(x, y) = cvPreview.GetPixel(x, y)
|
|
NEXT x
|
|
NEXT y
|
|
filePath = path
|
|
CheckSizeMenu
|
|
UpdateTitle
|
|
RefreshAll
|
|
END SUB
|
|
|
|
|
|
SUB mnuSave_Click
|
|
DIM path AS STRING
|
|
path = DlgFileSave$("Save Icon", SAVE_FILTER)
|
|
IF path = "" THEN
|
|
EXIT SUB
|
|
END IF
|
|
IF NOT SaveIcon(path) THEN
|
|
MsgBox "Could not save " + path + "."
|
|
EXIT SUB
|
|
END IF
|
|
filePath = path
|
|
dirty = False
|
|
UpdateTitle
|
|
lblStatus.Caption = "Saved: " + path
|
|
END SUB
|
|
|
|
|
|
' The printing library prints picture files, so the icon goes through a
|
|
' scratch copy in the TEMP folder (else the program's user folder).
|
|
SUB mnuPrint_Click
|
|
DIM tmp AS STRING
|
|
DIM title AS STRING
|
|
tmp = FileOpsTempDir$()
|
|
IF tmp = "" THEN
|
|
tmp = App.User
|
|
END IF
|
|
tmp = FileOpsPathJoin$(tmp, "PRINTICO.BMP")
|
|
IF NOT SaveIcon(tmp) THEN
|
|
MsgBox "Could not prepare the icon for printing."
|
|
EXIT SUB
|
|
END IF
|
|
IF filePath <> "" THEN
|
|
title = filePath
|
|
ELSE
|
|
title = "Untitled icon"
|
|
END IF
|
|
PrintPictureDialog tmp, title
|
|
KILL tmp
|
|
END SUB
|
|
|
|
|
|
SUB mnuExit_Click
|
|
Unload IconEd
|
|
END SUB
|
|
|
|
|
|
SUB mnuPencil_Click
|
|
SelectTool TOOL_PENCIL
|
|
END SUB
|
|
|
|
|
|
SUB mnuEraser_Click
|
|
SelectTool TOOL_ERASER
|
|
END SUB
|
|
|
|
|
|
SUB mnuPicker_Click
|
|
SelectTool TOOL_PICKER
|
|
END SUB
|
|
|
|
|
|
SUB mnuSize16_Click
|
|
ChangeSize SIZE_SMALL
|
|
END SUB
|
|
|
|
|
|
SUB mnuSize24_Click
|
|
ChangeSize SIZE_MEDIUM
|
|
END SUB
|
|
|
|
|
|
SUB mnuSize32_Click
|
|
ChangeSize MAX_ICON
|
|
END SUB
|
|
|
|
|
|
SUB cvEditor_MouseDown(button AS INTEGER, x AS INTEGER, y AS INTEGER)
|
|
DIM px AS INTEGER
|
|
DIM py AS INTEGER
|
|
px = x \ pixelSize
|
|
py = y \ pixelSize
|
|
IF curTool = TOOL_PICKER THEN
|
|
IF px >= 0 AND px < iconW AND py >= 0 AND py < iconH THEN
|
|
curColor = pixels(px, py)
|
|
DrawSelectedColor
|
|
SelectTool TOOL_PENCIL
|
|
END IF
|
|
EXIT SUB
|
|
END IF
|
|
drawing = True
|
|
SetIconPixel px, py
|
|
lblStatus.Caption = "(" + STR$(px) + "," + STR$(py) + ")"
|
|
END SUB
|
|
|
|
|
|
SUB cvEditor_MouseMove(button AS INTEGER, x AS INTEGER, y AS INTEGER)
|
|
DIM px AS INTEGER
|
|
DIM py AS INTEGER
|
|
px = x \ pixelSize
|
|
py = y \ pixelSize
|
|
IF px >= 0 AND px < iconW AND py >= 0 AND py < iconH THEN
|
|
lblStatus.Caption = "(" + STR$(px) + "," + STR$(py) + ")"
|
|
END IF
|
|
IF drawing THEN
|
|
SetIconPixel px, py
|
|
END IF
|
|
END SUB
|
|
|
|
|
|
SUB cvEditor_MouseUp(button AS INTEGER, x AS INTEGER, y AS INTEGER)
|
|
drawing = False
|
|
END SUB
|
|
|
|
|
|
SUB IconEd_QueryUnload(Cancel AS INTEGER)
|
|
IF NOT dirty THEN
|
|
EXIT SUB
|
|
END IF
|
|
DIM result AS INTEGER
|
|
result = DlgPromptSave("Icon Editor")
|
|
IF result = DVX_SAVE_YES THEN
|
|
mnuSave_Click
|
|
IF dirty THEN
|
|
Cancel = 1
|
|
END IF
|
|
ELSEIF result = DVX_SAVE_CANCEL THEN
|
|
Cancel = 1
|
|
END IF
|
|
END SUB
|
|
|
|
|
|
SUB cvPalette_MouseDown(button AS INTEGER, x AS INTEGER, y AS INTEGER)
|
|
DIM col AS INTEGER
|
|
DIM row AS INTEGER
|
|
DIM idx AS INTEGER
|
|
col = x \ PAL_CELL
|
|
row = y \ PAL_CELL
|
|
IF col >= 0 AND col < PAL_COLS AND row >= 0 AND row < PAL_ROWS THEN
|
|
idx = row * PAL_COLS + col
|
|
curColor = palette(idx)
|
|
DrawSelectedColor
|
|
IF curTool = TOOL_PICKER THEN
|
|
SelectTool TOOL_PENCIL
|
|
END IF
|
|
END IF
|
|
END SUB
|
|
|
|
|
|
SUB mnuHelpContents_Click
|
|
HelpView HELP_FILE
|
|
END SUB
|
|
|
|
|
|
SUB mnuAbout_Click
|
|
DIM msg AS STRING
|
|
msg = "Icon Editor" + CHR$(10) + CHR$(10)
|
|
msg = msg + "Draws small square pictures and icons." + CHR$(10) + CHR$(10)
|
|
msg = msg + "Copyright 2026 Scott Duensing"
|
|
MsgBox msg, vbOKOnly + vbInformation, "About Icon Editor"
|
|
END SUB
|