box.zc

来自「实现树形结构」· ZC 代码 · 共 2,624 行 · 第 1/4 页

ZC
2,624
字号
		button (e) = left mouse button
		status (e) = get key flags
		x (position (e)) = LOWORD (lParam) : short : int
		y (position (e)) = HIWORD (lParam) : short : int
		if on mouse double click (m, e)
			return 0
		end
//[cf]
//[c]
//[of]:	WM_CONTEXTMENU
//[c]
	case WM_CONTEXTMENU

		equ hwnd src = wParam : HWND
		def src = box from hwnd (hwnd src)
		if not nil (src)
			def pt: POINT
			x (pt) = LOWORD (lParam) : short : int
			y (pt) = HIWORD (lParam) : short : int
			if x (pt) >= 0 && y (pt) >=0
				ScreenToClient (hwnd src, pt)
			end
			
			def e: local popup event
			type (e) = popup event type
			x (position (e)) = x (pt)
			y (position (e)) = y (pt)
			if on popup (src, e)
				return 0
			end
		end

//[cf]
//[of]:	WM_GETMINMAXINFO
	case WM_GETMINMAXINFO
	
		// Set the min track from the box's min size
		def min track size = ptMinTrackSize (lParam:MINMAXINFO)
		x (min track size) = min width (m)
		y (min track size) = min height (m)
		return 0
//[cf]
//[of]:	WM_DROPFILES
	case WM_DROPFILES

		def e: local drop files event
		msg (e) = msg
		wParam (e) = wParam
		lParam (e) = lParam
		on drop files (m, e)
		return 0
//[cf]
//[of]:	WM_ACTIVATE
//[c]The activate message is re-posted in order to be handled after other events 
//[c]such as WM_BUTTONDOWN. This way, a dialog box can be opened
//[c]during the activation event and any capture can be cancelled.
//[c]
	case WM_ACTIVATE
		PostMessageA(hwnd (m), WM_DELAY_ACTIVATE, wParam, lParam)
//[cf]
	end

	return default window proc (m, msg, wParam, lParam)

end
//[cf]
//[cf]
//[of]:accessing
//[of]:set font (font)
public func set font (m: box, font: font)

	send message (m, WM_SETFONT, hFont (font):WPARAM, MAKELPARAM(1, 0))

end
//[cf]
//[of]:set label font (font)
public func set label font (m: box)

	if not nil (style (m))
		def font = label font (style (m))
		if not nil (font)
			set font (m, font)
		end
	end

end
//[cf]
//[of]:set edit font (font)
public func set edit font (m: box)

	if not nil (style (m))
		def font = edit font (style (m))
		if not nil (font)
			set font (m, font)
		end
	end

end
//[cf]
//[c]
//[of]:set window text (text)
//[c]
public func set window text (m: box, text: string)
	if not nil (hwnd (m))
		SetWindowTextA (hwnd (m), text)
	end
end
//[cf]
//[of]:set style (style)
//[c]Changes the style and force update
//[c]
public func set style (m: box, style: LONG)

	SetWindowLongA (hwnd (m), GWL_STYLE, style)
	SetWindowPos (
		hwnd (m), 
		nil:HWND,
		0,
		0,
		0,
		0,
		(SWP_FRAMECHANGED | 
		SWP_NOACTIVATE | 
		SWP_NOCOPYBITS | 
		SWP_SHOWWINDOW | 
		SWP_NOMOVE | 
		SWP_NOOWNERZORDER | 
		SWP_NOSIZE | 
		SWP_NOZORDER):UINT)
	
end
//[cf]
//[of]:parent handle
//[c]
public func parent handle (m: box)
	return hwnd (parent (m))
end
//[cf]
//[c]
//[of]:base style
public func base style (m: box)

	def style = WS_CHILD | WS_CLIPSIBLINGS

	if is visible (m)
		style |= WS_VISIBLE
	end

	if ~ is enabled (m)
		style |= WS_DISABLED
	end

	return style

end
//[cf]
//[c]
//[of]:do move (rectangle, repaint)
//[c]Move the box
//[c]
//[c]The position of a box should be changed only by its parent from
//[c]the on size or adjust event.
//[c]
public func do move (m: box, r: rectangle, repaint: bool)
	// the windows method will send back the WM_SIZE message
	// that emits a moved();
	MoveWindow (
		hwnd (m),
		x (r),
		y (r),
		w (r),
		h (r),
		BOOL (repaint))
end
//[cf]
//[of]:do set enable (bool)
//[c]
public func do set enable (m: box, en: bool)

	// exit if unchanged
	if enabled (m) == en
		return
	end
	
	def state: int
	if en
		state = 1 
	else 
		state = 0
	end
	EnableWindow (hwnd (m), state)
	invalidate (m)
	
	enabled (m) = en

end
//[cf]
//[c]
//[of]:activate
//[c]Under Windows, widgets are always activated
//[c]
public equ activate (m: box)
	// empty
end
//[cf]
//[of]:activated
//[c]Under Windows, widgets are always activated
//[c]
public equ activated (m: box) = true
//[cf]
//[cf]
//[of]:private
//[of]:globals
//[c]
//[c]The box being created.
//[c]Used during initialization of a window before the userdata is set
//[c]
private def box being created = nil: box
//[cf]
//[c]
//[of]:insert child (box)
//[c]
private func insert child (parent: box, child: box)

	parent (child) = parent
	next sibling (child) = nil
	prev sibling (child) = last child (parent)
	
	// update the head of the list
	if is nil (first child (parent))
		first child (parent) = child
	end
	
	// update successor
	def last = last child (parent)
	if not nil (last)
		next sibling (last) = child
	end

	// update the tail of the list
	last child (parent) = child

end
//[cf]
//[of]:remove child (box)
//[c]Removes a child box
//[c]
private func remove child (parent: box, child: box)

	if first child (parent) == child
		first child (parent) = next sibling (child)
	end
	
	if last child (parent) == child
		last child (parent) = prev sibling (child)
	end

	if not nil (prev sibling (child))
		next sibling (prev sibling (child)) = next sibling (child)
	end

	if not nil (next sibling (child))
		prev sibling (next sibling (child)) = prev sibling (child)
	end

	next sibling (child) = nil
	prev sibling (child) = nil
	parent (child) = nil

end
//[cf]
//[cf]
//[cf]
//[c]
//[of]:conversion functions
//[of]:rectangle from RECT (rectangle, LPRECT)
//[c]Converts a windows rectangle to local format
//[c]
public func rectangle from RECT (dst: rectangle, src: LPRECT)
	
	x (dst) = left (src)
	y (dst) = top (src)
	w (dst) = right (src) - left (src)
	h (dst) = bottom (src) - top (src)

end
//[cf]
//[of]:RECT from rectangle (LPRECT, rectangle)
//[c]Converts a local rectangle to  windows format
//[c]
public func RECT from rectangle (dst: LPRECT, src: rectangle)

	left (dst) = x (src)
	top (dst) = y (src)
	right (dst) = right (src)
	bottom (dst) = bottom (src)

end
//[cf]
//[of]:width (LPRECT)
//[c]
public equ width (r: LPRECT) = right (r) - left (r)
//[cf]
//[of]:height (LPRECT)
//[c]
public equ height (r: LPRECT) = bottom (r) - top (r)
//[cf]
//[of]:BOOL (bool)
//[c]
public equ BOOL (b:bool) = b : BOOL
//[cf]
//[cf]
//[of]:utility functions
//[of]:box from hwnd (hwnd)
//[c]Returns the box from a window handle
//[c]
public func box from hwnd (hwnd: HWND)
	return GetWindowLongA (hwnd, GWL_USERDATA) : box
end
//[cf]
//[of]:get key flags
//[c]
public func get key flags

	def status = 0
	
	if GetKeyState (VK_SHIFT) < 0:s
		status |= SHIFT
	end
	
	if GetKeyState (VK_CONTROL) < 0:s
		status |= CTRL
	end

	if GetKeyState (VK_MENU) < 0:s
		status |= ALT
	end

	return status

end
//[cf]
//[of]:get focus box
//[c]
public func get focus box
	def hwnd = GetFocus
	if is nil (hwnd)
		return nil
	end
	return box from hwnd (hwnd)
end
//[cf]
//[cf]
//[of]:entry point
//[of]:WinMain
//[c]
//[c]application entry point
import func run (int, [] string): int
//[c]
public func[name="c", call="__stdcall", entry point="true"] WinMain(
		hInst : HINSTANCE,
		hPrevInst : HINSTANCE,
		szCmdLine : string,
		iCmdShow : int): LRESULT

	// Save parameters in global variables
	hinstance = hInst
	cmd show = iCmdShow

	def init: INITCOMMONCONTROLSEX
	dwSize (init) = sizeof INITCOMMONCONTROLSEX
	dwICC  (init) = ICC_TAB_CLASSES
	if InitCommonControlsEx (init) == FALSE
		return -1
	end

	def show mem info opt := "-debug"
	def cmd line = szCmdLine
	def show mem info = false
	if starts with (cmd line, show mem info opt)
		cmd line += size (show mem info opt)
		while is blank (cmd line [])
			++ cmd line
		end
		show mem info = true
	end

	initialize allocator
	initialize string buffer
	initialize system commands
	initialize commands
	initialize timer

	equ max args = 64
	def argc = 0
	def argv : [max args] string
	argv [argc++] = empty string

	def p = szCmdLine
	def quote = nul char
	def text = false
	
	repeat
		def c = p []
		if c == nul char
			break
		elsif quote <> nul char
			if c == quote
				text = false
				quote = nul char
				p [] = nul char
			elsif ~ text
				argv [argc++] = p
				text = true
			end
		elsif is blank (c)
			p [] = nul char
			text = false
		elsif (c == $' || c == $" || c == $`) && ~ text
			quote = c
		elsif ~ text
			argv [argc++] = p
			text = true
		end
		p += 1
	end
	
	def result = run (argc, argv) : LRESULT

	release commands
	release system commands
	release string buffer
	
	if show mem info || left block > 0
		// copy stats before creating string buffer
		def tc = total block
		def lc = left block
		def lb = left bytes
		def mb = max bytes
		
		def stats = temp string buffer
		stats << "Number of allocations...: " << tc << \n
		stats << "Max allocated...: " << mb << " (" << (mb+1023)/1024 << "K)" << \n
		stats << "Left bytes...: " << lb << " (" << (lb+1023)/1024 << "K)" << \n
		stats << "Left blocks...: " << lc << \n
		MessageBoxA (NULL:HWND, as string (stats), "Memory Leaks", MB_OK)
		release (stats)
	end
	
	release allocator

	return result
end
//[cf]
//[cf]
//[of]:globals
//[c]
//[c]Program instance handle
//[c]
public def hinstance : HINSTANCE
//[c]
//[c]Parameters to show the main window
//[c]
public def cmd show: int
//[cf]
//[cf]
//[c]
//[of]:constants
//[c]Identifier for the platform
//[c]
public def user interface name := "win32"
//[cf]
//[of]:basic types
//[c]
public typedef interface = object
public typedef interface id = object
public typedef resource id = int
//[c]
//[c]Use this type to declare a new type of event for other event
//[c]
public typedef local event type = [1] byte
public typedef event type = -> local event type
//[c]
public enum border style
	border none
	border single
	border sunken
end
//[c]
public enum mouse button
	left mouse button
	middle mouse button
	right mouse button
end
//[cf]
//[of]:events
//[of]:event types
public def destroy event type : local event type
public def focus event type : local event type
public def blur event type : local event type
public def key down event type : local event type
public def key up event type : local event type
public def char event type : local event type
public def mouse down event type : local event type
public def mouse up event type : local event type
public def mouse move event type : local event type
public def mouse wheel event type : local event type
public def mouse cancel event type : local event type
public def mouse double click event type : local event type
public def popup event type : local event type
public def enter menu event type : local event type
public def leave menu event type : local event type

public def value changed event type : local event type
public def selection changed event type : local event type
public def index changed event type : local event type
public def click event type : local event type
//[cf]
//[of]:event
public struct event
	type: event type
end
//[c]
public func event (t: event type, return e: event)
	type (e) = t
end
//[cf]
//[c]
//[of]:key event
public struct key event : local event
	key: int
	status: int
end
//[c]
public func key event (type: event type, key: int, status: int, return e: key event)
	e . type = type
	e . key = key
	e . status = status
end
//[cf]
//[of]:char event
public struct char event : local event
	char code: char
	private _pad: [3] byte // ### compiler bug
	status: int
end
//[c]
public func char event (c: char, s: int, return e: char event)
	e . type = char event type
	e . char code = c
	e . status = s
end
//[cf]
//[of]:mouse button event
public struct mouse button event : local event
	button: mouse button
	status: int
	position: local point
end
//[cf]
//[of]:mouse move event
public struct mouse move event : local event
	status: int
	position: local point
end
//[cf]
//[of]:mouse wheel event
public struct mouse wheel event : local event
	status: int
	delta: int
	position: local point
end
//[cf]
//[of]:popup event
public struct popup event : local event
	position: local point
end
//[cf]
//[c]
//[of]:drop files event
public struct drop files event
	private msg: UINT
	private wParam: WPARAM
	private lParam:  LPARAM
end
//[c]
//[c]
//[c]Enumerates all files of a drop event
//[c]
public equ each file (m: drop files event)

	def hdrop = wParam (m) : HDROP
	
	def n = DragQueryFileA (hdrop, 0xFFFFFFFF, nil:LPSTR, 0)
	def i = 0:d
	while i < n
		def name : [MAX_PATH] char
		DragQueryFileA (hdrop, i, name, MAX_PATH)
		yield (name)
		++ i
	end
	DragFinish (hdrop)

end
//[cf]
//[of]:receive primary selection event
public struct receive primary selection event
	format: clipboard format
	buffer: [] byte
	size: size
end
//[cf]
//[of]:query primary selection event
public struct query primary selection event
	format: clipboard format
	data: object
end
//[cf]
//[cf]
//[of]:box style
//[of]:type
//[c]Every box has a a style. A box uses this object's attributes to 
//[c]display itself.
//[c]
public struct box style

	// style for edits
	edit color: color
	edit background: color
	edit font: font
	edit border: border style
	
	// style for labels
	label color: color
	label background: color
	label font: font
	label alignment: alignment

	button highlight color: color
	button shadow color: color

end
//[cf]
//[cf]
//[of]:box
//[of]:type
public struct box : local sys box

	class: box class
	parent: box
	style: box style
	first child: box
	last child: box
	next sibling: box
	prev sibling: box
	

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?