本帖最后由 Byaidu 于 2018-4-30 12:10 编辑
image3.5包含了许多重大更新
包括绘图命令的完善以及绘图脚本的模块化
添加了“图元”和“画布”的概念
load pic mypic.bmp
上面这条命令的作用就是把mypic.bmp图片加载为一个叫pic的“图元”,然后再把这个pic“图元”绘制到一个叫pic的同名“画布”
然后mouse功能就会通过cmd“画布”的图元索引树来判定用户点击的了哪个“图元”
“图元”在image里只是一个虚拟的概念,只使用方便判定碰撞箱,不占用实际内存
“画布”在image里是一个实体的概念,没有对应的碰撞箱,仅用来承载“图元”,每个“画布”都有对应的HDC,会占用实际内存
其实我是想投到开源原创工具版块里的,不过貌似等级不够,所以就先投在这里了
image
控制台显示图片 Ver 3.5 by Byaidu
help 显示帮助
load tag [file] 新建画布tag,并加载图片file为图元tag,再将图元tag绘制到画布tag
unload tag 删除画布tag
save tag file 将画布tag的内容存储到file中
target tag 切换当前绘图目标为画布tag
buffer tag [w] [h] [r] [g] [b ] 新建画布tag,并新建一个颜色为rgb(默认为白色)、大小为w*h(默认为当前绘图目标的大小)图元tag,再将图元tag绘制到画布tag
resize tag w h 将画布tag缩放到w*h的大小,如果目标cmd,则会同时将控制台设置为最适合绘图的状态
info tag 将画布tag的宽和高存储到变量image
rotate tag degree 将画布tag顺时针旋转degree度
draw tag x y [trans [r] [g] [b ] | alpha a] 将画布tag绘制到当前绘图目标的x,y位置上
若指定了trans,则以rgb为透明色(默认为白色)
若指定了alpha,则以a为透明度
font r g b [w] [h] 设置当前绘图目标所用字体的rgb值和大小
text string 在当前绘图目标的x,y的位置上输出字符串string
getpix tag x y 将画布tag上x,y位置的rgb值存储到变量image
setpix tag x y r g b 设置画布tag上x,y位置的rgb值
cls 清空画布cmd的内容
export 将画布cmd的句柄存储到变量image
import tag handle 通过句柄将另一个控制台的画布cmd映射到此控制台的画布tag
sleep time 延时time毫秒
list file [label] 执行image指令脚本file,若指定了label则会直接跳转到脚本中的标签label
exit 退出当前image指令脚本
union tag 合并图层tag中的所有图元成一个与图层tag同名的图元tag
debug 以图形形式输出图元索引树,用于查看画布cmd上的各个图元
mouse time [region1] [region2] ... 捕获鼠标坐标及事件,坐标以像素为单位,时间以毫秒为单位
若time>=0,当发生点击事件或时间超过限制时会将鼠标坐标x,y以及坐标在画布cmd上所在图元tag的tag存储到变量image,并将图元tag的tag单独再存储到变量errorlevel
若time<0,不设置时间限制
若指定了region,那么返回的的就不是图元tag的tag而是region的序号,如果鼠标坐标不在任何一个指定的region中,则返回序号0
region应以如下的形式给出:x1,y1,x2,y2
核心代码
image.cpp | | | | | | | | | | | | | | | #define _CRT_SECURE_NO_WARNINGS | | #define _CRT_NON_CONFORMING_SWPRINTFS | | #include <windows.h> | | #include <gdiplus.h> | | #include <wchar.h> | | #include <iostream> | | #include <fstream> | | #include <string> | | #include <cstdio> | | #include <map> | | #include "regionmgr.cpp" | | using namespace std; | | using namespace Gdiplus; | | | | #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) | | #define DLL_EXPORT __declspec(dllexport) | | #define wtoi _wtoi | | #define wcsicmp _wcsicmp | | #define match(x,y) if (wstring(argv[x])==wstring(y)||wstring(argv[x]).substr(0,2)==wstring(y).substr(0,2)) | | #define matchclsid(x,y) if (wstring(argv[x]).substr(wstring(argv[x]).length()-3)==wstring(y)) | | #pragma comment(lib,"msimg32.lib") | | #pragma comment(lib,"GdiPlus.lib") | | | | struct imageres { | | HDC dc; | | HBITMAP oldbmp; | | int w, h; | | BUF region; | | imageres() {}; | | imageres(wchar_t *file) | | { | | BITMAP bi; | | | | dc = CreateCompatibleDC(nullptr); | | | | HBITMAP bmp; | | Bitmap *bm = new Bitmap(file); | | bm->GetHBITMAP(0, &bmp); | | delete bm; | | oldbmp = (HBITMAP)SelectObject(dc, bmp); | | GetObject(bmp, sizeof(BITMAP), &bi); | | w = bi.bmWidth; | | h = bi.bmHeight; | | } | | void regioninit(wchar_t *tag,int w,int h) {region = BUF(tag, w - 1, h - 1);} | | }*hTarget; | | map<wstring, imageres> resmap; | | HWND hCMD; | | double scale; | | | | void image(wchar_t *); | | void Init_image(); | | | | bool WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved) | | { | | switch (dwReason) | | { | | case DLL_PROCESS_ATTACH: | | | | DisableThreadLibraryCalls(hModule); | | Init_image(); | | break; | | case DLL_PROCESS_DETACH: | | break; | | } | | return true; | | } | | extern "C" DLL_EXPORT int WINAPI Init(void) | | { | | return 0; | | } | | extern "C" __declspec(dllexport) void call(wchar_t *varName, wchar_t *varValue) | | { | | | | if (!wcsicmp(varName, L"image")) image(varValue); | | return; | | } | | | | void Init_image() | | { | | GdiplusStartupInput gdiplusStartupInput; | | ULONG_PTR gdiplusToken; | | GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr); | | | | imageres hRes; | | | | hCMD = GetConsoleWindow(); | | HDC hDC = GetDC(hCMD); | | DEVMODE dm; | | dm.dmSize = sizeof(DEVMODE); | | EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dm); | | int ax = dm.dmPelsWidth; | | int bx = GetSystemMetrics(SM_CXSCREEN); | | scale = (double)ax / bx; | | RECT rc; | | GetClientRect(hCMD, &rc); | | hRes.dc = hDC; | | hRes.w = int(scale*(rc.right - rc.left)); | | hRes.h = int(scale*(rc.bottom - rc.top)); | | hRes.regioninit((wchar_t*)L"cmd", hRes.w, hRes.h); | | resmap[L"cmd"] = hRes; | | hTarget = &resmap[L"cmd"]; | | | | hDC = GetDC(nullptr); | | hRes.dc = hDC; | | hRes.w = dm.dmPelsWidth; | | hRes.h = dm.dmPelsHeight; | | hRes.regioninit((wchar_t*)L"desktop", hRes.w, hRes.h); | | resmap[L"desktop"] = hRes; | | | | TextOutA(hTarget->dc, 0, 0, 0, 0); | | return; | | } | | imageres * getres(wchar_t *tag) | | { | | if (!resmap.count(tag)) | | { | | imageres hRes(tag); | | hRes.regioninit(tag, hRes.w, hRes.h); | | resmap[tag] = hRes; | | } | | return &resmap[tag]; | | } | | void delres(wchar_t *tag) | | { | | imageres * hRes = getres(tag); | | HBITMAP bmp = (HBITMAP)SelectObject(hRes->dc, hRes->oldbmp); | | DeleteObject(bmp); | | DeleteDC(hRes->dc); | | resmap.erase(tag); | | return; | | } | | | | HBITMAP copyhbitmap(imageres *hSrc) | | { | | imageres hRes; | | hRes.dc = CreateCompatibleDC(hSrc->dc); | | HBITMAP hBitmap = CreateCompatibleBitmap(hSrc->dc, hSrc->w, hSrc->h); | | hRes.oldbmp = (HBITMAP)SelectObject(hRes.dc, hBitmap); | | BitBlt(hRes.dc, 0, 0, hSrc->w, hSrc->h, hSrc->dc, 0, 0, SRCCOPY); | | SelectObject(hRes.dc, hRes.oldbmp); | | DeleteDC(hRes.dc); | | return hBitmap; | | } | | void rotateres(wchar_t **argv) | | { | | imageres * hRes = getres(argv[1]); | | HBITMAP hSrc = copyhbitmap(hRes); | | Rect rect(0, 0, hRes->w, hRes->h); | | | | Bitmap bitmap(hSrc, nullptr); | | BitmapData bitmapData; | | bitmap.LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &bitmapData); | | byte* pixels = (byte*)bitmapData.Scan0; | | | | Bitmap bitmap2(hSrc, nullptr); | | BitmapData bitmapData2; | | bitmap2.LockBits(&rect, ImageLockModeWrite, PixelFormat24bppRGB, &bitmapData2); | | byte* pixels2 = (byte*)bitmapData2.Scan0; | | | | double pi = 3.1415926; | | double angle = -(double)wtoi(argv[2]) / 180 * pi; | | double sina = sin(angle), cosa = cos(angle); | | int cx = hRes->w / 2, cy = hRes->h / 2; | | for (int i = 0; i<hRes->w; i++) | | for (int j = 0; j<hRes->h; j++) | | { | | int x = (int)(cx + (i - cx)*cosa - (j - cy)*sina), y = (int)(cy + (i - cx)*sina + (j - cy)*cosa); | | if (x >= 0 && x < hRes->w&&y >= 0 && y < hRes->h) | | { | | for (int k = 0; k < 3; k++) | | pixels2[j*bitmapData2.Stride + 3 * i + k] = pixels[y*bitmapData.Stride + 3 * x + k]; | | } | | else | | { | | for (int k = 0; k < 3; k++) | | pixels2[j*bitmapData2.Stride + 3 * i + k] = 0xFF; | | } | | } | | bitmap.UnlockBits(&bitmapData); | | bitmap2.UnlockBits(&bitmapData2); | | | | HDC hDCMem = CreateCompatibleDC(hRes->dc); | | HBITMAP hBitmap; | | bitmap2.GetHBITMAP(0, &hBitmap); | | HBITMAP oldbmp = (HBITMAP)SelectObject(hDCMem, hBitmap); | | BitBlt(hRes->dc, 0, 0, hRes->w, hRes->h, hDCMem, 0, 0, SRCCOPY); | | | | DeleteObject(hSrc); | | SelectObject(hDCMem, oldbmp); | | DeleteObject(hBitmap); | | DeleteDC(hDCMem); | | } | | void alphares(wchar_t **argv) | | { | | double alpha = (double)wtoi(argv[5])/255; | | | | imageres * hRes = getres(argv[1]); | | HBITMAP hSrc = copyhbitmap(hRes); | | Rect rect(0, 0, hRes->w, hRes->h); | | Bitmap bitmap(hSrc, nullptr); | | BitmapData bitmapData; | | bitmap.LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &bitmapData); | | byte* pixels = (byte*)bitmapData.Scan0; | | | | | | HBITMAP hSrc2 = copyhbitmap(hTarget); | | Rect rect2(0, 0, hTarget->w, hTarget->h); | | Bitmap bitmap2(hSrc2, nullptr); | | BitmapData bitmapData2; | | bitmap2.LockBits(&rect2, ImageLockModeRead, PixelFormat24bppRGB, &bitmapData2); | | byte* pixels2 = (byte*)bitmapData2.Scan0; | | | | Rect rect3(0, 0, hTarget->w, hTarget->h); | | Bitmap bitmap3(hSrc2, nullptr); | | BitmapData bitmapData3; | | bitmap3.LockBits(&rect3, ImageLockModeWrite, PixelFormat24bppRGB, &bitmapData3); | | byte* pixels3 = (byte*)bitmapData3.Scan0; | | | | int cx = wtoi(argv[2]), cy = wtoi(argv[3]); | | for (int i = 0; i<hTarget->w; i++) | | for (int j = 0; j<hTarget->h; j++) | | { | | int x = i - cx, y = j - cy; | | if (x >= 0 && x < hRes->w&&y >= 0 && y < hRes->h) | | { | | for (int k = 0; k < 3; k++) | | pixels3[j*bitmapData3.Stride + 3 * i + k] = | | (byte)((1 - alpha) * pixels2[j*bitmapData2.Stride + 3 * i + k] + | | alpha * pixels[y*bitmapData.Stride + 3 * x + k]); | | } | | else | | { | | for (int k = 0; k < 3; k++) | | pixels3[j*bitmapData3.Stride + 3 * i + k] = pixels2[j*bitmapData2.Stride + 3 * i + k]; | | } | | } | | bitmap.UnlockBits(&bitmapData); | | bitmap2.UnlockBits(&bitmapData2); | | bitmap3.UnlockBits(&bitmapData3); | | | | HDC hDCMem = CreateCompatibleDC(hTarget->dc); | | HBITMAP hBitmap; | | bitmap3.GetHBITMAP(0, &hBitmap); | | HBITMAP oldbmp = (HBITMAP)SelectObject(hDCMem, hBitmap); | | BitBlt(hTarget->dc, 0, 0, hTarget->w, hTarget->h, hDCMem, 0, 0, SRCCOPY); | | | | DeleteObject(hSrc); | | DeleteObject(hSrc2); | | SelectObject(hDCMem, oldbmp); | | DeleteObject(hBitmap); | | DeleteDC(hDCMem); | | } | | | | void image(wchar_t *CmdLine) | | { | | | | int argc; | | wchar_t **argv; | | argv = CommandLineToArgvW(CmdLine, &argc); | | match(0, L"help") | | { | | printf( | | "image\n" | | "控制台显示图片 Ver 3.5 by Byaidu\n" | | ); | | } | | match(0, L"load") | | { | | wchar_t *tag = argv[1]; | | | | if (resmap.count(tag)) delres(tag); | | imageres hRes(argc > 2 ? argv[2] : argv[1]); | | hRes.regioninit(tag, hRes.w, hRes.h); | | resmap[tag] = hRes; | | } | | match(0, L"unload") | | { | | | | delres(argv[1]); | | } | | match(0, L"save") | | { | | imageres * hRes = getres(argv[1]); | | HBITMAP hSrc = copyhbitmap(hRes); | | Rect rect(0, 0, hRes->w, hRes->h); | | Bitmap bitmap(hSrc, nullptr); | | | | CLSID Clsid; | | matchclsid(2, L"bmp") CLSIDFromString(L"{557cf400-1a04-11d3-9a73-0000f81ef32e}", &Clsid); | | matchclsid(2, L"jpg") CLSIDFromString(L"{557cf401-1a04-11d3-9a73-0000f81ef32e}", &Clsid); | | matchclsid(2, L"png") CLSIDFromString(L"{557cf406-1a04-11d3-9a73-0000f81ef32e}", &Clsid); | | bitmap.Save(argv[2], &Clsid, nullptr); | | DeleteObject(hSrc); | | } | | match(0, L"target") | | { | | hTarget = getres(argv[1]); | | } | | match(0, L"buffer") | | { | | wchar_t *tag = argv[1]; | | | | if (resmap.count(tag)) delres(tag); | | imageres hRes; | | hRes.dc = CreateCompatibleDC(hTarget->dc); | | HBITMAP hBitmap = CreateCompatibleBitmap(hTarget->dc,argc>2?wtoi(argv[2]):hTarget->w,argc>3?wtoi(argv[3]):hTarget->h); | | hRes.oldbmp = (HBITMAP)SelectObject(hRes.dc, hBitmap); | | int color = argc>6?RGB(wtoi(argv[4]),wtoi(argv[5]),wtoi(argv[6])):RGB(255,255,255); | | colorregion(hRes.dc, color, 0, 0, hTarget->w - 1, hTarget->h - 1); | | hRes.w = hTarget->w; | | hRes.h = hTarget->h; | | | | hRes.regioninit(tag, hRes.w, hRes.h); | | resmap[tag] = hRes; | | } | | match(0, L"resize") | | { | | imageres * hRes = getres(argv[1]); | | match(1,L"cmd") | | { | | | | | | HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); | | HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); | | DWORD oldConMode; | | GetConsoleMode(hIn, &oldConMode); | | SetConsoleMode(hIn, (oldConMode | ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT)&(~ENABLE_QUICK_EDIT_MODE)); | | | | CONSOLE_CURSOR_INFO cursor_info = { (DWORD)25, FALSE }; | | SetConsoleCursorInfo(hOut, &cursor_info); | | | | RECT rc,rc2; | | SetScrollRange(hCMD, 0, 0, 0, 1); | | SetScrollRange(hCMD, 1, 0, 0, 1); | | GetClientRect(hCMD, &rc); | | GetWindowRect(hCMD, &rc2); | | int w = (rc2.right - rc2.left) - (rc.right - rc.left) + int((wtoi(argv[2])) / scale); | | int h = (rc2.bottom - rc2.top) - (rc.bottom - rc.top) + int((wtoi(argv[3])) / scale); | | | | | | | | MoveWindow(hCMD, rc2.left, rc2.top, w, h, 0); | | Sleep(10); | | SetScrollRange(hCMD, 0, 0, 0, 1); | | SetScrollRange(hCMD, 1, 0, 0, 1); | | Sleep(10); | | hRes->w = (int)wtoi(argv[2]); | | hRes->h = (int)wtoi(argv[3]); | | }else{ | | HDC hDCMem = CreateCompatibleDC(hRes->dc); | | HBITMAP hBitmap = CreateCompatibleBitmap(hRes->dc, wtoi(argv[2]), wtoi(argv[3])); | | HBITMAP oldbmp = (HBITMAP)SelectObject(hDCMem, hBitmap); | | StretchBlt(hDCMem, 0, 0, wtoi(argv[2]), wtoi(argv[3]), hRes->dc, 0, 0, hRes->w, hRes->h, SRCCOPY); | | | | HBITMAP bmp = (HBITMAP)SelectObject(hRes->dc, hRes->oldbmp); | | DeleteObject(bmp); | | DeleteDC(hRes->dc); | | | | hRes->oldbmp = oldbmp; | | hRes->dc = hDCMem; | | hRes->w = wtoi(argv[2]); | | hRes->h = wtoi(argv[3]); | | } | | hRes->regioninit(argv[1], hRes->w, hRes->h); | | } | | match(0, L"cls") | | { | | | | imageres * hRes = getres((wchar_t*)L"cmd"); | | hRes->regioninit((wchar_t*)L"cmd", hRes->w, hRes->h); | | InvalidateRect(hCMD, nullptr, true); | | UpdateWindow(hCMD); | | Sleep(10); | | } | | match(0, L"rotate") | | { | | rotateres(argv); | | } | | match(0, L"draw") | | { | | | | imageres * hRes = getres(argv[1]); | | | | BUF clearbuf(L"", hRes->region.p->x2, hRes->region.p->y2); | | complexupdate(clearbuf.p, 0, 0, hRes->region.p->x2, hRes->region.p->y2, wtoi(argv[2]), wtoi(argv[3]), hTarget->region.p); | | complexupdate(hRes->region.p, 0, 0, hRes->region.p->x2, hRes->region.p->y2, wtoi(argv[2]), wtoi(argv[3]), hTarget->region.p); | | if (argc == 4) | | { | | BitBlt(hTarget->dc, wtoi(argv[2]), wtoi(argv[3]), hRes->w, hRes->h, hRes->dc, 0, 0, SRCCOPY); | | } | | else | | { | | match(4, L"trans") | | TransparentBlt(hTarget->dc, wtoi(argv[2]), wtoi(argv[3]), hRes->w, hRes->h, hRes->dc, 0, 0, hRes->w, hRes->h, argc==8?RGB(wtoi(argv[5]),wtoi(argv[6]),wtoi(argv[7])):RGB(255, 255, 255)); | | match(4, L"alpha") | | alphares(argv); | | } | | } | | match(0, L"text") | | { | | | | for (int i = 0; i < 2;i++) TextOutW(hTarget->dc, wtoi(argv[2]), wtoi(argv[3]), argv[1], wcslen(argv[1])); | | } | | match(0, L"font") | | { | | SetBkMode(hTarget->dc, TRANSPARENT); | | SetTextColor(hTarget->dc, RGB(wtoi(argv[1]), wtoi(argv[2]), wtoi(argv[3]))); | | if (argc > 4) | | { | | HFONT hFont = CreateFontW( | | argc > 5 ? wtoi(argv[5]) : 0, | | argc > 4 ? wtoi(argv[4]) : 0, | | argc > 6 ? wtoi(argv[6]) : 0, | | argc > 7 ? wtoi(argv[7]) : 0, | | argc > 8 ? wtoi(argv[8]) : 400, | | argc > 9 ? wtoi(argv[9]) : 0, | | argc > 10 ? wtoi(argv[10]) : 0, | | argc > 11 ? wtoi(argv[11]) : 0, | | DEFAULT_CHARSET, | | OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, | | DEFAULT_QUALITY, | | FF_DONTCARE, | | argc > 12 ? argv[12] : L"新宋体" | | ); | | SelectObject(hTarget->dc, hFont); | | } | | } | | match(0, L"sleep") | | { | | Sleep(wtoi(argv[1])); | | } | | match(0, L"info") | | { | | wchar_t info[100]; | | imageres * hRes = getres(argv[1]); | | swprintf(info, L"%d %d", hRes->w, hRes->h); | | SetEnvironmentVariableW(L"image", info); | | } | | match(0, L"export") | | { | | wchar_t info[100]; | | swprintf(info, L"%d", (int)hCMD); | | SetEnvironmentVariableW(L"image", info); | | } | | match(0, L"import") | | { | | wchar_t *tag = argv[1]; | | | | if (resmap.count(tag)) delres(tag); | | imageres hRes; | | | | HWND hCMD2 = (HWND)wtoi(argv[2]); | | HDC hDC = GetDC(hCMD2); | | DEVMODE dm; | | dm.dmSize = sizeof(DEVMODE); | | EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dm); | | int ax = dm.dmPelsWidth; | | int bx = GetSystemMetrics(SM_CXSCREEN); | | double scale = (double)ax / bx; | | RECT rc; | | GetClientRect(hCMD2, &rc); | | hRes.dc = hDC; | | hRes.w = (int)ceil(scale*(rc.right - rc.left)); | | hRes.h = (int)ceil(scale*(rc.bottom - rc.top)); | | hRes.regioninit(tag, hRes.w, hRes.h); | | resmap[tag] = hRes; | | } | | match(0, L"getpix") | | { | | wchar_t info[100]; | | COLORREF color=GetPixel(hTarget->dc, wtoi(argv[1]), wtoi(argv[2])); | | swprintf(info, L"%d %d %d", GetRValue(color), GetGValue(color), GetBValue(color)); | | SetEnvironmentVariableW(L"image", info); | | } | | match(0, L"setpix") | | { | | SetPixel(hTarget->dc, wtoi(argv[1]), wtoi(argv[2]), RGB(wtoi(argv[3]), wtoi(argv[4]), wtoi(argv[5]))); | | } | | match(0, L"list") | | { | | bool skip = 0; | | if (argc > 2) skip = 1; | | ifstream in(argv[1]); | | string str; | | wchar_t wstr[100]; | | while (!in.eof()) | | { | | getline(in, str); | | MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wstr, sizeof(wstr)); | | if (skip&&L":" + wstring(argv[2]) == wstring(wstr)) { skip = 0; continue; } | | if (skip) continue; | | if (wstring(L"exit") == wstring(wstr)) break; | | | | image(wstr); | | } | | in.close(); | | } | | match(0, L"mouse") | | { | | imageres *hRes = getres((wchar_t*)L"cmd"); | | wchar_t info[100]; | | POINT mosPos; | | int x, y; | | int timer = wtoi(argv[1]); | | | | | | HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); | | HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); | | DWORD oldConMode; | | GetConsoleMode(hIn, &oldConMode); | | SetConsoleMode(hIn, (oldConMode | ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT)&(~ENABLE_QUICK_EDIT_MODE)); | | if (timer < 0) | | { | | INPUT_RECORD Rec; | | DWORD res; | | while (1) | | { | | ReadConsoleInputW(hIn, &Rec, 1, &res); | | if (Rec.EventType == MOUSE_EVENT) | | { | | if (Rec.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) | | { | | GetCursorPos(&mosPos); | | ScreenToClient(hCMD, &mosPos); | | x = min(max((int)scale*mosPos.x, 0), hRes->w); | | y = min(max((int)scale*mosPos.y, 0), hRes->h); | | break; | | } | | } | | | | | | | | | | | | | | | | | | | | } | | } | | if (timer >= 0) | | { | | DWORD tstart = GetTickCount(); | | while (!(KEYDOWN(VK_LBUTTON) || int(GetTickCount() - tstart) >= timer)) Sleep(10); | | GetCursorPos(&mosPos); | | ScreenToClient(hCMD, &mosPos); | | x = min(max((int)scale*mosPos.x, 0), hRes->w); | | y = min(max((int)scale*mosPos.y, 0), hRes->h); | | } | | if (argc >= 3) | | { | | | | int ret = 0; | | for (int i = 2; i < argc; i++) | | { | | int x1, y1, x2, y2; | | swscanf(argv[i], L"%d,%d,%d,%d", &x1, &y1, &x2, &y2); | | if (x >= x1 && x <= x2 && y >= y1 && y <= y2) ret = i - 1; | | } | | swprintf(info, L"%d %d %d", x, y, ret); | | SetEnvironmentVariableW(L"image", info); | | swprintf(info, L"%d", ret); | | SetEnvironmentVariableW(L"errorlevel", info); | | }else{ | | | | wstring ret = query(resmap[L"cmd"].region.p, x, y); | | swprintf(info, L"%d %d %s", x, y, ret.c_str()); | | SetEnvironmentVariableW(L"image", info); | | swprintf(info, L"%s", ret.c_str()); | | SetEnvironmentVariableW(L"errorlevel", info); | | } | | SetConsoleMode(hIn, oldConMode); | | } | | match(0, L"debug") | | { | | imageres *hRes = getres((wchar_t*)L"cmd"); | | show(hRes->region.p); | | } | | match(0, L"union") | | { | | | | imageres * hRes = getres(argv[1]); | | hRes->regioninit(argv[1], hRes->w, hRes->h); | | } | | match(0, L"cmd") | | { | | _wsystem(argv[1]); | | } | | | | LocalFree(argv); | | return; | | }COPY |
regionmgr.cpp | #pragma once | | #include <windows.h> | | #include <cstdio> | | #include <iostream> | | #include <algorithm> | | #include <map> | | #include <stack> | | #include <ctime> | | using namespace std; | | | | struct P{ | | int single; | | wstring src; | | int x1, y1, x2, y2, x0, y0; | | P *l, *r; | | }; | | struct BUF{ | | P *p; | | BUF(){}; | | BUF(wstring src,int w,int h){ | | p = new P{ 1,src,0,0,w,h,0,0 }; | | } | | }; | | map<wstring,BUF> bufmap; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | void singleunion(P *p) | | { | | if (p->r->single == 1 && p->l->single == 1 && p->r->src == p->l->src&& | | p->r->x1 - p->l->x1 == p->r->x0 - p->l->x0&& | | p->r->y1 - p->l->y1 == p->r->y0 - p->l->y0) | | { | | p->x0 = p->l->x0; | | p->y0 = p->l->y0; | | p->src = p->l->src; | | p->single = 1; | | | | return; | | } | | if (p->r->single &&p->r->x1== p->x1&&p->r->y1 == p->y1&&p->r->x2 == p->x2&&p->r->y2 == p->y2) | | { | | p->x0 = p->r->x0; | | p->y0 = p->r->y0; | | p->src = p->r->src; | | p->single = 1; | | return; | | } | | if (p->l->single &&p->l->x1 == p->x1&&p->l->y1 == p->y1&&p->l->x2 == p->x2&&p->l->y2 == p->y2) | | { | | p->x0 = p->l->x0; | | p->y0 = p->l->y0; | | p->src = p->l->src; | | p->single = 1; | | return; | | } | | } | | | | void singleupdate(P *p,int x1,int y1,int x2,int y2,int x0,int y0, wstring v,int now=0) | | { | | if (p->single==1&&p->x1==x1&&p->y1==y1&&p->x2==x2&&p->y2==y2){ | | if (!(p->x0==x0&&p->y0==y0&&p->src==v)){ | | p->x0=x0,p->y0=y0,p->src=v; | | | | | | | | | | | | | | } | | return; | | } | | if (p->single){ | | if (now) { | | if (x1 != p->x1) { | | p->l = new P{ 1,p->src ,p->x1, p->y1, x1 - 1, p->y2, p->x0, p->y0 }; | | p->r = new P{ 1,p->src ,x1,p->y1,p->x2,p->y2,p->x0 + x1 - p->x1,p->y0 }; | | singleupdate(p->r, x1, y1, x2, y2, x0, y0, v, !now); | | } | | else { | | p->l = new P{ 1,p->src ,p->x1,p->y1,x2,p->y2,p->x0,p->y0 }; | | p->r = new P{ 1,p->src ,x2 + 1,p->y1,p->x2,p->y2,p->x0 + x2 + 1 - p->x1,p->y0 }; | | singleupdate(p->l, x1, y1, x2, y2, x0, y0, v, !now); | | } | | } | | else { | | if (y1 != p->y1) { | | p->l = new P{ 1,p->src ,p->x1, p->y1, p->x2, y1 - 1, p->x0, p->y0 }; | | p->r = new P{ 1,p->src ,p->x1,y1,p->x2,p->y2,p->x0,p->y0 + y1 - p->y1 }; | | singleupdate(p->r, x1, y1, x2, y2, x0, y0, v, !now); | | } | | else { | | p->l = new P{ 1,p->src ,p->x1,p->y1,p->x2,y2,p->x0,p->y0 }; | | p->r = new P{ 1,p->src ,p->x1,y2 + 1,p->x2,p->y2,p->x0,p->y0 + y2 + 1 - p->y1 }; | | singleupdate(p->l, x1, y1, x2, y2, x0, y0, v, !now); | | } | | } | | p->single=0; | | }else{ | | if (now){ | | if (x2<= p->l->x2) singleupdate(p->l,x1,y1,x2,y2,x0,y0,v,!now); | | else if (x1>= p->r->x1) singleupdate(p->r,x1,y1,x2,y2,x0,y0,v,!now); | | else singleupdate(p->l,x1,y1, p->l->x2,y2,x0,y0,v,!now),singleupdate(p->r,p->r->x1,y1,x2,y2,x0+p->r->x1-x1,y0,v,!now); | | }else{ | | if (y2<= p->l->y2) singleupdate(p->l,x1,y1,x2,y2,x0,y0,v,!now); | | else if (y1>= p->r->y1) singleupdate(p->r,x1,y1,x2,y2,x0,y0,v,!now); | | else singleupdate(p->l,x1,y1,x2, p->l->y2,x0,y0,v,!now),singleupdate(p->r,x1,p->r->y1,x2,y2,x0,y0+p->r->y1-y1,v,!now); | | } | | } | | singleunion(p); | | } | | | | void complexupdate(P *p,int x1,int y1,int x2,int y2,int x0,int y0,P *v,int now=0) | | { | | if (p->single){ | | singleupdate(v,x0,y0,x0+x2-x1,y0+y2-y1,p->x0+x1-p->x1,p->y0+y1-p->y1,p->src); | | return; | | } | | if (now){ | | if (x2<= p->l->x2) complexupdate(p->l,x1,y1,x2,y2,x0,y0,v,!now); | | else if (x1>= p->r->x1) complexupdate(p->r,x1,y1,x2,y2,x0,y0,v,!now); | | else complexupdate(p->l,x1,y1, p->l->x2,y2,x0,y0,v,!now),complexupdate(p->r, p->r->x1,y1,x2,y2,x0+p->r->x1-x1,y0,v,!now); | | }else{ | | if (y2<= p->l->y2) complexupdate(p->l,x1,y1,x2,y2,x0,y0,v,!now); | | else if (y1>= p->r->y1) complexupdate(p->r,x1,y1,x2,y2,x0,y0,v,!now); | | else complexupdate(p->l,x1,y1,x2, p->l->y2,x0,y0,v,!now),complexupdate(p->r,x1, p->r->y1,x2,y2,x0,y0+p->r->y1-y1,v,!now); | | } | | } | | | | void colorregion(HDC hDC,int color,int x1,int y1,int x2,int y2) | | { | | HPEN gPen = CreatePen(PS_SOLID, 1, color); | | HBRUSH gBrush = CreateSolidBrush(color); | | HPEN oPen = (HPEN)SelectObject(hDC, gPen); | | HBRUSH oBrush = (HBRUSH)SelectObject(hDC, gBrush); | | | | Rectangle(hDC, x1, y1, x2 + 1, y2 + 1); | | | | | | SelectObject(hDC, oPen); | | SelectObject(hDC, oBrush); | | DeleteObject(gPen); | | DeleteObject(gBrush); | | } | | | | | | void show(P *p) | | { | | HWND hCMD = GetConsoleWindow(); | | HDC hDC = GetDC(hCMD); | | if (p->single){ | | int color = rand() % 16777216; | | colorregion(hDC, color, p->x1, p->y1, p->x2, p->y2); | | } else { | | | | show(p->l); | | show(p->r); | | } | | ReleaseDC(hCMD,hDC); | | } | | wstring query(P *p, int x, int y, int now = 0) | | { | | if (p->single) return p->src; | | if (now) { | | if (x <= p->l->x2) return query(p->l, x, y, !now); | | else return query(p->r, x, y, !now); | | } else { | | if (y <= p->l->y2) return query(p->l, x, y, !now); | | else return query(p->r, x, y, !now); | | } | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | COPY |
下面展示的这个样例,借助于image脚本的模块化,成功实现了界面与逻辑分离
x.bat | @echo off | | %1start /b "" "%~dp0cmd.exe" "/c %~fs0 :"&exit | | setlocal EnableDelayedExpansion | | set image=draw button1.bmp 500 500 | | set image=list x.txt init | | | | :act1 | | set image=list x.txt act1 | | set image=list x.txt !errorlevel! | | if "!errorlevel!"=="cmd" goto act1 | | call:act1_!errorlevel! | | goto act2 | | | | :act1_button1 | | rem to do something | | goto:eof | | | | :act1_button2 | | rem to do something | | goto:eof | | | | :act2 | | set image=list x.txt act2 | | set image=list x.txt !errorlevel! | | if "!errorlevel!"=="cmd" goto act2 | | | | :act3 | | set image=list x.txt act3 | | set image=list x.txt !errorlevel! | | if "!errorlevel!"=="cmd" goto act3 | | | | echo 演示完毕 | | pauseCOPY |
x.txt | :init | | resize cmd 1000 1000 | | load button1 button1.bmp | | draw button1.bmp 0 0 | | load button2 button2.bmp | | font 0 255 255 50 100 | | text "加载完成" 0 0 | | mouse -1 | | cls | | exit | | | | :act1 | | text "ACT 1" 0 0 | | draw button1 100 500 | | draw button2 600 500 | | mouse -1 | | cls | | exit | | | | :act2 | | text "ACT 2" 0 0 | | draw button1 100 500 alpha 100 | | draw button2 600 500 alpha 100 | | mouse -1 | | cls | | exit | | | | :act3 | | text "ACT 3" 0 0 | | draw button1 100 500 alpha 50 | | draw button2 600 500 alpha 50 | | mouse -1 | | cls | | exit | | | | :button1 | | text "YOU CLICK BUTTON 1" 0 100 | | exit | | | | :button2 | | text "YOU CLICK BUTTON 2" 0 100 | | exit | | | | :cmd | | text "YOU CLICK NOTHING" 0 100 | | exitCOPY |
更多精彩样例尽在:https://github.com/Byaidu/image |