import win.ui;
/*DSG{{*/
var winform=win.form(text="简单的形状画板练习 (点右键弹菜单)"; right=775; bottom=479)
/*}}*/
winform.enableDpiScaling("init");
var shapes= {}; //存储需要绘制形状的表
/**表中内容
[1]={
style = 1/*rect*/|2/*ellipse*/; //形状样式
color=0x0000ff; //形状颜色
rect= ::RECT(); //形状区域
z=#shapes+1 //形状z序
};
...
**/
var selID=0;
var newStyle=1; //新建图形的样式
var newColor=1; //新建图形的颜色
var selRc=false //鼠标正在选中的形状
var isDrawing=false //鼠标正在绘制形状
var tmpRc= ::RECT() //存储橡皮筋矩形框
var hdc= ::GetDC(winform.hwnd);
//初始化弹出菜单项
var popmenu=win.ui.popmenu(winform);
popmenu.add("绘制矩形", function(id) {
newStyle=1;
});
popmenu.add("绘制椭圆", function(id) {
newStyle=2;
});
//下面代码控制矩形的【缩放】
//小方块gif
var imggp='GIF89a\x07\0\x07\0\x80\0\0\xFF\xFF\xFF\0\0\x80!\xF9\x04\0\0\0\0\0,\0\0\0\0\x07\0\x07\0\0\x02\x0C\x84o\xA1\x9A\x1B\xBD \x03\xEE\xA1S\0\0;';
winform.add(
gpTopLeft= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=1;
}
gpTop= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=2;
}
gpTopRight= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=3;
}
gpLeft= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=4;
}
gpRight= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=5;
}
gpBottomLeft= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=6;
}
gpBottom= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=7;
}
gpBottomRight= {
cls="picturebox"; left=0; top=0; right=0; bottom=0; image=imggp; autoResize=0; notify=1; z=8;
}
)
{
var gps= {
winform.gpTopLeft;
winform.gpTop;
winform.gpTopRight;
winform.gpLeft;
winform.gpRight;
winform.gpBottomLeft;
winform.gpBottom;
winform.gpBottomRight;
};
showgps=function(rc) {
var left=rc.left - 7;
var top=rc.top - 7;
var right=rc.right;
var bottom=rc.bottom;
var center=rc.left / 2+rc.right / 2 - 3;
var middle=rc.top / 2+rc.bottom / 2 - 3;
winform.gpTopLeft.setPos(left, top, 7, 7, 0);
winform.gpTop.setPos(center, top, 7, 7, 0);
winform.gpTopRight.setPos(right, top, 7, 7, 0);
winform.gpLeft.setPos(left, middle, 7, 7, 0);
winform.gpRight.setPos(right, middle, 7, 7, 0);
winform.gpBottomLeft.setPos(left, bottom, 7, 7, 0);
winform.gpBottom.setPos(center, bottom, 7, 7, 0);
winform.gpBottomRight.setPos(right, bottom, 7, 7, 0);
}
hidegps=function() {
winform.gpTopLeft.setPos(0, 0, 0, 0, 1);
winform.gpTop.setPos(0, 0, 0, 0, 1);
winform.gpTopRight.setPos(0, 0, 0, 0, 1);
winform.gpLeft.setPos(0, 0, 0, 0, 1);
winform.gpRight.setPos(0, 0, 0, 0, 1);
winform.gpBottomLeft.setPos(0, 0, 0, 0, 1);
winform.gpBottom.setPos(0, 0, 0, 0, 1);
winform.gpBottomRight.setPos(0, 0, 0, 0, 1);
}
var minW, minH = 30, 30;
var limitbound= {
//限制边界位置
function(x, y, rc, fRc) {
if(x<0)x=0;
if(y<0)y=0;
if(x>=rc.right)x=rc.right-minW;
if(y>=rc.bottom)y=rc.bottom-minH;
return x, y;
};
function(x, y, rc, fRc) {
if(y<0)y=0;
if(y>=rc.bottom)y=rc.bottom-minH;
return x, y;
};
function(x, y, rc, fRc) {
if(x<=rc.left)x=rc.left+minW;
if(y<0)y=0;
if(x>fRc.right)x=fRc.right;
if(y>=rc.bottom)y=rc.bottom-minH;
return x, y;
};
function(x, y, rc, fRc) {
if(x<0)x=0;
if(x>=rc.right)x=rc.right-minW;
return x, y;
};
function(x, y, rc, fRc) {
if(x<=rc.left)x=rc.left+minW;
if(x>fRc.right)x=fRc.right;
return x, y;
};
function(x, y, rc, fRc) {
if(x<0)x=0;
if(y<=rc.top)y=rc.top+minH;
if(x>=rc.right)x=rc.right-minW;
if(y>fRc.bottom)y=fRc.bottom;
return x, y;
};
function(x, y, rc, fRc) {
if(y<=rc.top)y=rc.top+minH;
if(y>fRc.bottom)y=fRc.bottom;
return x, y;
};
function(x, y, rc, fRc) {
if(x<=rc.left)x=rc.left+minW;
if(y<=rc.top)y=rc.top+minH;
if(x>fRc.right)x=fRc.right;
if(y>fRc.bottom)y=fRc.bottom;
return x, y;
};
};
var newRect={
function(rc, x1, y1, x2, y2) {
rc.move(x2-x1, y2-y1);
return rc;
};
function(rc, x1, y1, x2, y2) {
rc.move(0, y2-y1);
return rc;
};
function(rc, x1, y1, x2, y2) {
rc.move(0, y2-y1);
rc.expand(x2-x1, 0);
return rc;
};
function(rc, x1, y1, x2, y2) {
rc.move(x2-x1, 0);
return rc;
};
function(rc, x1, y1, x2, y2) {
rc.expand(x2-x1, 0);
return rc;
};
function(rc, x1, y1, x2, y2) {
rc.move(x2-x1, 0);
rc.expand(0, y2-y1);
return rc;
};
function(rc, x1, y1, x2, y2) {
rc.expand(0, y2-y1);
return rc;
};
function(rc, x1, y1, x2, y2) {
rc.expand(x2-x1, y2-y1);
return rc;
};
};
var loadcurse= {
//cursestyle
0x7F82;
0x7F85;
0x7F83;
0x7F84;
0x7F84;
0x7F83;
0x7F85;
0x7F82;
}
for (i=1; #gps) {
gps[ i].wndproc= {
[0x201 /*_WM_LBUTTONDOWN*/]=function () {
gps[ i].isDown=true gps[ i].capture=true isDrawing=false;
var x, y=win.getMessagePos() gps[i].x1,
gps[i].y1=win.toClient(winform.hwnd, x, y);
tmpRc=shapes[selID].rect.copy()
::DrawFocusRect(hdc, tmpRc);
};
[0x200 /*_WM_MOUSEMOVE*/]=function() {
if(gps[i].isDown) {
var x, y=win.toClient(winform.hwnd, win.getMessagePos())
::DrawFocusRect(hdc, tmpRc);
x, y=limitbound[i](x, y, shapes[selID].rect, winform.clientRect) //边界限制
tmpRc=newRect[i](tmpRc, gps[i].x1, gps[i].y1, x, y)
::DrawFocusRect(hdc, tmpRc);
gps[i].x1, gps[i].y1=x, y
}
};
[0x202 /*_WM_LBUTTONUP*/]=function() {
shapes[selID].rect=tmpRc.copy()
showgps(shapes[selID].rect)
gps[i].isDown=false
gps[i].capture=false
winform.redraw()
}
[0x20 /*_WM_SETCURSOR*/]=function() {
win.cur.setCur(win.cur.load(loadcurse[i]));
return true;
}
}
}
}
//下面代码控制矩形的【选中&移动&右键菜单&删除】
import win.cur;
var moveCur=win.cur.load(32646/*_IDC_SIZEALL*/)
import win.ui.menu;
winform.wndproc=function(hwnd, message, wParam, lParam) {
select(message) {
case 0x201 /*_WM_LBUTTONDOWN*/ {
x1, y1=win.getMessagePos(lParam);
if(#shapes>0) {
for(i=#shapes; 1; -1) {
//判断鼠标是否在矩形内
if(shapes[i].style==1 and shapes[i].rect.contains(x1, y1)) {
selRc=true;
selID=i break;
}
//判断鼠标是否在椭圆内
if(shapes[i].style==2 and shapes[i].rect.contains(x1, y1)) {
var a=shapes[i].rect.width() / 2;
var b=shapes[i].rect.height() / 2;
var x=x1 - shapes[i].rect.left - a;
var y=y1 - shapes[i].rect.top - b;
if(((x/a)**2+(y/b)**2)<=1) {
//判断鼠标在有效的椭圆面积内
selRc=true;
selID=i break;
}
}
}
}
if(selRc) {
winform.capture=true win.cur.setCur(moveCur);
isDrawing=false;
var v=shapes[selID]
tmpRc=v.rect.copy() //图像前置一下
select(v.style) {
case 1 /*rect*/ {
gdi.fillRect(hdc, v.color, v.rect)
}
case 2 /*ellipse*/ {
var brush=::CreateSolidBrush(v.color)
::SelectObject(hdc, brush)
::Ellipse(hdc, v.rect.ltrb())
::DeleteObject(brush)
}
case 3 /*line*/ {}
}
//画一个选中的边框
var hBrush= ::CreateSolidBrush(0x0000FF) //red
::SelectObject(hdc, hBrush)
::FrameRect(hdc, tmpRc)
::DeleteObject(hBrush);
showgps(tmpRc)
}
else {
hidegps(); selID=0
}
}
case 0x200/*_WM_MOUSEMOVE*/ {
if(selRc) {
win.cur.setCur(moveCur);
::DrawFocusRect(hdc, tmpRc)
var x, y=win.getMessagePos();
x, y=win.toClient(hwnd, x, y);
tmpRc.offset(x-x1, y-y1) //移动tmpRc
//边界限制
if(tmpRc.right<=0) tmpRc.setPos(30-tmpRc.width(), , , )
if(tmpRc.bottom<=0) tmpRc.setPos(, 30-tmpRc.height(), , )
if(tmpRc.left>=winform.clientRect.width()) tmpRc.setPos(winform.clientRect.width()-30, , , )
if(tmpRc.top>=winform.clientRect.height()) tmpRc.setPos(, winform.clientRect.height()-30, , )
::DrawFocusRect(hdc, tmpRc);
x1, y1 = x, y;
}
}
case 0x202 /*_WM_LBUTTONUP*/ {
if(selRc) {
shapes[selID].rect=tmpRc.copy()
showgps(shapes[selID].rect)
selRc=false
winform.capture=false
winform.invalidate()
}
}
case 0x205 /*_WM_RBUTTONUP*/ {
if(selID) {
//在选中的形状上弹出
var popmenu2=win.ui.popmenu(winform);
popmenu2.add("删除此形状", function() {
table.remove(shapes, selID) selID=0 selRc=false hidegps() winform.invalidate()
})
var x, y=win.getMessagePos(lParam);
if(shapes[selID].rect.contains(x, y)) popmenu2.popup()
}
else {
//在窗体在空白位置(无形状位置)弹出
var mouseOnsharp=false;
var x, y=win.getMessagePos(lParam);
for(k, v in shapes) {
if(v.rect.contains(x, y)) {
mouseOnsharp=true break;
}
}
if(not mouseOnsharp) {
//修改菜单项的checked状态
popmenu.check(1, (newStyle==1)) popmenu.check(2, (newStyle==2)) popmenu.popup()
}
}
}
case 0xF /*_WM_PAINT*/ {
var ps=PAINTSTRUCT();
var hdc, ps= ::BeginPaint(hwnd, ps) //绘制所有形状
for(k, v in shapes) {
select(v.style) {
case 1 /*rect*/ {
gdi.fillRect(hdc, v.color, v.rect)
}
case 2 /*ellipse*/ {
var brush=::CreateSolidBrush(v.color)
::SelectObject(hdc, brush)
::Ellipse(hdc, v.rect.ltrb())
::DeleteObject(brush)
}
case 3 /*line*/ {}
}
}
::EndPaint(hwnd, ps);
}
}
}
//下面代码控制【新建形状】
z_max=0;
winform.wndproc=function(hwnd, message, wParam, lParam) {
select(message) {
case 0x201 /*_WM_LBUTTONDOWN*/ {
if( !selRc) {
isDrawing=true;
x1, y1=win.getMessagePos(lParam);
tmpRc=::RECT(x1, y1, x1, y1)
}
}
case 0x200 /*_WM_MOUSEMOVE*/ {
if( !selRc && isDrawing) {
var x, y=win.getMessagePos(lParam);
::DrawFocusRect(hdc, tmpRc) tmpRc.expand(x-x1, y-y1)
::DrawFocusRect(hdc, tmpRc) x1, y1=x, y
}
}
case 0x202 /*_WM_LBUTTONUP*/ {
if( !selRc && isDrawing) {
isDrawing=false;
if(tmpRc.left>tmpRc.right) {
var t=tmpRc.left
tmpRc.left=tmpRc.right
tmpRc.right=t
}
if(tmpRc.top>tmpRc.bottom) {
var t=tmpRc.top
tmpRc.top=tmpRc.bottom
tmpRc.bottom=t
}
newColor=gdi.RGB(math.random(150, 250), math.random(50, 250), math.random(0, 150));
z_max++;
var arr= {
style=newStyle;
color=newColor;
rect=tmpRc;
z=z_max;
};
table.push(shapes, arr);
winform.invalidate()
}
}
}
}
winform.show();
win.loopMessage();