# aardio 范例: 桌面圆形时钟

```aardio
import win.ui;
/*DSG{{*/
var winform = win.form(text="桌面圆形时钟";right=284;bottom=251)
winform.add(
clockFace={cls="plus";left=7;top=10;right=277;bottom=240;db=1;dl=1;dr=1;dt=1;font=LOGFONT(name='Arial Narrow');forecolor=0xE9FFE9;z=1}
)
/*}}*/

// 自定义绘制时钟
winform.clockFace.onDrawContent = function(graphics,rc,txtColor,rcContent,foregroundColor,font){

	// 获取控件窗口当前 DPI 缩放后的 1 像素宽高,用于调整刻度线宽度等
	var dpiX, dpiY = owner.dpiScale(1, 1);

	var centerX = rc.width() / 2;
	var centerY = rc.height() / 2;
	var radius = math.min(centerX, centerY);

	// 绘制圆形背景
	var brush = gdip.solidBrush(foregroundColor);
	graphics.fillEllipse(brush, ::RECT2(centerX - radius, centerY - radius, radius * 2, radius * 2));
	brush.delete(); // 释放画刷资源

	radius = radius - 10 * dpiX; // 钟盘半径,留出一些边距
	
	// 获取当前时间
	var now = time();
	var hour = now.hour % 12; // 转换为12小时制
	var minute = now.minute;
	var second = now.second;
	var milliseconds = now.milliseconds; 
	
	// 绘制时钟刻度 (分钟刻度)
	var hourMarkInnerOffset = 35; // 小时刻度内侧
	var hourMarkOuterOffset = 10; // 小时刻度外侧
	var minuteMarkInnerOffset = 25; // 分钟刻度内侧
	var minuteMarkOuterOffset = 10; // 分钟刻度外侧

	var hourMarkWidth = 4; // 小时刻度线宽度
	var minuteMarkWidth = 1; // 分钟刻度线宽度

	for(i = 0; 59; 1) { // 循环60次,绘制60个刻度
		var angle = i * 6 * math.pi / 180; // 每分钟6度

		var currentInnerOffset = minuteMarkInnerOffset;
		var currentOuterOffset = minuteMarkOuterOffset;
		var currentMarkWidth = minuteMarkWidth;

		if (i % 5 == 0) { // 每5个刻度（即小时刻度）
			currentInnerOffset = hourMarkInnerOffset;
			currentOuterOffset = hourMarkOuterOffset;
			currentMarkWidth = hourMarkWidth;
		}

		var pen = gdip.pen(0xFF000000, currentMarkWidth); // 黑色画笔
		var x1 = centerX + (radius - currentInnerOffset) * math.cos(angle - math.pi/2);
		var y1 = centerY + (radius - currentInnerOffset) * math.sin(angle - math.pi/2);

		var x2 = centerX + (radius - currentOuterOffset) * math.cos(angle - math.pi/2);
		var y2 = centerY + (radius - currentOuterOffset) * math.sin(angle - math.pi/2);
		graphics.drawLine(pen, x1, y1, x2, y2);
		pen.delete(); // 释放画笔资源
	}

	// 绘制小时数字
	var numberBrush = gdip.solidBrush(0xFF000000); // 数字颜色 (黑色)
	var strformat = gdip.stringformat();
	strformat.align = 1; // 水平居中
	strformat.lineAlign = 1; // 垂直居中

	var numberRadius = radius - 65; // 数字距离圆心的距离 (调整以适应字体大小)

	for(h = 1; 12; 1) { // 循环12次,绘制1-12的数字
		var displayHour = h;
		// 计算数字的角度,12点在顶部 (-math.pi/2)
		var hourAngle = (h % 12) * 30 * math.pi / 180 - math.pi/2;

		var textX = centerX + numberRadius * math.cos(hourAngle);
		var textY = centerY + numberRadius * math.sin(hourAngle);

		// 为数字创建一个小的矩形区域,用于drawString的布局
		var textRectWidth = 60; // 预估数字文本的宽度
		var textRectHeight = 60; // 预估数字文本的高度
		var textRect = ::RECTF(textX - textRectWidth/2, textY - textRectHeight/2, textRectWidth, textRectHeight);

		graphics.drawString(tostring(displayHour), font, textRect, strformat, numberBrush);
	}

	// 释放画刷和字符串格式资源
	numberBrush.delete();
	strformat.delete();

	// 绘制时针
	// 时针角度：(小时 + 分钟/60) * 30度
	var hourAngle = (hour + minute/60) * 30 * math.pi / 180;
	var hourPen = gdip.pen(0xFF000000, 6); // 黑色,6像素宽
	var hourX = centerX + (radius * 0.5) * math.cos(hourAngle - math.pi/2);
	var hourY = centerY + (radius * 0.5) * math.sin(hourAngle - math.pi/2);
	graphics.drawLine(hourPen, centerX, centerY, hourX, hourY);
	hourPen.delete(); // 释放画笔资源

	// 绘制分针
	// 分针角度：(分钟 + 秒/60) * 6度
	var minuteAngle = (minute + (second + milliseconds/1000) / 60) * 6 * math.pi / 180;
	var minutePen = gdip.pen(0xFF000000, 4); // 黑色,4像素宽
	var minuteX = centerX + (radius * 0.65) * math.cos(minuteAngle - math.pi/2);
	var minuteY = centerY + (radius * 0.65) * math.sin(minuteAngle - math.pi/2);
	graphics.drawLine(minutePen, centerX, centerY, minuteX, minuteY);
	minutePen.delete(); // 释放画笔资源
	
	// 绘制秒针
	var secondAngle = (second + milliseconds/1000) * 6 * math.pi / 180;
	var secondPen = gdip.pen(0xFFFF0000, 2); // 红色,2像素宽
	var secondX = centerX + (radius * 0.7) * math.cos(secondAngle - math.pi/2);
	var secondY = centerY + (radius * 0.7) * math.sin(secondAngle - math.pi/2);
	graphics.drawLine(secondPen, centerX, centerY, secondX, secondY);
	secondPen.delete(); // 释放画笔资源

	// 绘制中心点
	var centerBrush = gdip.solidBrush(0xFF000000); // 黑色画刷
	graphics.fillEllipse(centerBrush, centerX - 5, centerY - 5, 10, 10);
	centerBrush.delete(); // 释放画刷资源

	return true; // 阻止继续绘制前景色或前景图像,因为我们已经完全自定义了绘制内容
}

// 设置定时器更新时钟，间隔越小则移动越平滑占用 CPU 也越大。
winform.setInterval(250, function(){
	winform.clockFace.redraw(); // 重绘时钟
});

//使窗口背景透明
import win.ui.layered;
win.ui.layered(winform);

//允许拖动窗体
winform.onMouseDown  = function(wParam,lParam){
	winform.hitCaption()	
}

//右键菜单
import win.ui.menu;
winform.wndproc = {
	[0x204/*_WM_RBUTTONDOWN*/] = function(hwnd,message,wParam,lParam){ 
		var menu = win.ui.popmenu(winform);
		menu.add("退出",function(){
			winform.close();
		});
		menu.popup();
	}
}

winform.show();
win.loopMessage();
```