📄 winspec.cpp
字号:
unsigned char* PasteText()
{
HANDLE hmem = 0;
unsigned char *ptr, *ret=0L;
OpenClipboard(MainWnd);
if((hmem = GetClipboardData(CF_TEXT)) && (ptr = (unsigned char*) GlobalLock(hmem))){
ret = (unsigned char*) strdup((char*)ptr);
}
if(hmem) GlobalUnlock(hmem);
CloseClipboard();
return ret;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Get display (desktop) size
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void GetDesktopSize(int *width, int *height)
{
RECT rc;
GetClientRect(GetDesktopWindow(), &rc);
*width = rc.right;
*height = rc.bottom;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Common code for any Windows output class
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool com_oTextOut(int x, int y, char *txt, int cb,
HFONT *hFont, HDC *dc, TextDEF *td, bool win95mode, anyOutput *o)
{
XFORM xf;
w_char *uc;
int i, ix, iy, align;
if(!*hFont || !txt || !txt[0]) return false;
SelectObject(*dc, *hFont);
SetTextColor(*dc, td->ColTxt);
SetBkColor(*dc, td->ColBg);
align = ((td->Align & TXA_HRIGHT) ? TA_RIGHT : (td->Align &
TXA_HCENTER) ? TA_CENTER : TA_LEFT) | ((td->Align & TXA_VBOTTOM) ?
TA_BOTTOM : TA_TOP);
SetTextAlign(*dc, align);
SetBkMode(*dc, td->Mode ? TRANSPARENT : OPAQUE);
ix = iy = 0;
if(td->Style & TXS_SUB) {
if((td->Align & TXA_VCENTER) == TXA_VCENTER) iy += o->un2iy(td->fSize*0.4);
else if((td->Align & TXA_VBOTTOM) == TXA_VBOTTOM) iy += o->un2iy(td->fSize*0.2);
else if((td->Align & TXA_VTOP) == TXA_VTOP) iy += o->un2iy(td->fSize*.6);
}
else if(td->Style & TXS_SUPER) {
if((td->Align & TXA_VCENTER) == TXA_VCENTER) iy -= o->un2iy(td->fSize*0.4);
else if((td->Align & TXA_VBOTTOM) == TXA_VBOTTOM) iy -= o->un2iy(td->fSize*0.6);
else if((td->Align & TXA_VTOP) == TXA_VTOP) iy += o->un2iy(td->fSize*.0);
}
if(!win95mode && (fabs(td->RotBL) >.01 || fabs(td->RotCHAR) >.01)) {
SetGraphicsMode(*dc, GM_ADVANCED);
xf.eM11 = xf.eM22 = (float)cos(td->RotBL *0.01745329252);
xf.eM12 = (float)-sin(td->RotBL *0.01745329252);
xf.eM21 = -xf.eM12;
xf.eDx = (float)x;
xf.eDy = (float)y;
SetWorldTransform(*dc, &xf);
if(td->Font==FONT_GREEK && (uc=(w_char*)calloc(strlen(txt)+1, sizeof(w_char)))) {
for(i = 0; txt[i]; i++) {
if((txt[i] >= 'A' && txt[i] <= 'Z')) uc[i] = txt[i] - 'A' + 0x391;
else if((txt[i] >= 'a' && txt[i] <= 'z')) uc[i] = txt[i] - 'a' + 0x3B1;
else uc[i] = txt[i];
}
TextOutW(*dc, ix, iy+((td->Align & TXA_VCENTER) ? - td->iSize/2 : 0), uc,
(cb > 0) ? cb : strlen(txt));
free(uc);
}
else {
TextOut(*dc, ix, iy+((td->Align & TXA_VCENTER) ? - td->iSize/2 : 0), txt,
(cb > 0) ? cb : strlen(txt));
}
// DrawText(*dc, txt, (cb> 0)? cb : strlen(txt), 0L /*LPRECT*/, uFormat);
ModifyWorldTransform(*dc, &xf, MWT_IDENTITY);
SetGraphicsMode(*dc, GM_COMPATIBLE);
return true;
}
else {
if(!win95mode && td->Font==FONT_GREEK && (uc=(w_char*)calloc(strlen(txt)+1, sizeof(w_char)))) {
for(i = 0; txt[i]; i++) {
if((txt[i] >= 'A' && txt[i] <= 'Z')) uc[i] = txt[i] - 'A' + 0x391;
else if((txt[i] >= 'a' && txt[i] <= 'z')) uc[i] = txt[i] - 'a' + 0x3B1;
else uc[i] = txt[i];
}
TextOutW(*dc, x+ix, iy + ((td->Align & TXA_VCENTER) ? y - td->iSize/2 : y), uc,
(cb > 0) ? cb : strlen(txt));
free(uc);
return true;
}
else if(TextOut(*dc, x+ix, iy + ((td->Align & TXA_VCENTER) ? y - td->iSize/2 : y), txt,
(cb > 0) ? cb : strlen(txt))) return true;
}
return false;
}
bool com_SetTextSpec(TextDEF *set, anyOutput *o, HFONT *hFont, TextDEF *TxtSet,
HDC *dc, bool win95mode)
{
bool IsModified, RetVal;
LOGFONT FontRec;
HFONT newFont;
if(!set->iSize && set->fSize > 0.001f) set->iSize = o->un2iy(set->fSize);
if(!set->iSize) return false;
if(!*hFont || TxtSet->iSize != set->iSize || TxtSet->Style != set->Style ||
TxtSet->RotBL != set->RotBL || TxtSet->RotCHAR != set->RotCHAR ||
TxtSet->Font != set->Font || TxtSet->fSize != set->fSize) IsModified = true;
else IsModified = false;
RetVal = o->anyOutput::SetTextSpec(set);
if (IsModified && RetVal) {
// create font
if((TxtSet->Style & TXS_SUPER) || (TxtSet->Style & TXS_SUB))
FontRec.lfHeight = o->un2iy(set->fSize*0.71);
else FontRec.lfHeight = TxtSet->iSize;
if(FontRec.lfHeight <8) FontRec.lfHeight = 8;
FontRec.lfWidth = 0;
if(win95mode) { //Win 95, 98
FontRec.lfEscapement = iround(TxtSet->RotBL*10); //text angle
FontRec.lfOrientation = iround(TxtSet->RotBL*10); //base line angle
}
else { //Win NT, 2000, XP
FontRec.lfEscapement = 0; //text angle
FontRec.lfOrientation = 0; //base line angle
}
FontRec.lfWeight = (TxtSet->Style & TXS_BOLD) ? FW_BOLD : FW_NORMAL;
FontRec.lfItalic = (TxtSet->Style & TXS_ITALIC) ? TRUE : FALSE;
FontRec.lfUnderline = (TxtSet->Style & TXS_UNDERLINE) ? TRUE : FALSE;
FontRec.lfStrikeOut = 0;
FontRec.lfOutPrecision = OUT_DEFAULT_PRECIS;
FontRec.lfClipPrecision = CLIP_DEFAULT_PRECIS;
FontRec.lfQuality = PROOF_QUALITY;
switch(TxtSet->Font){
case FONT_HELVETICA:
default:
FontRec.lfCharSet = ANSI_CHARSET;
FontRec.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
strcpy(FontRec.lfFaceName, "Arial");
break;
case FONT_GREEK: case FONT_TIMES:
FontRec.lfCharSet = ANSI_CHARSET;
FontRec.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
strcpy(FontRec.lfFaceName, "Times New Roman");
break;
case FONT_COURIER:
FontRec.lfCharSet = ANSI_CHARSET;
FontRec.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
strcpy(FontRec.lfFaceName, "Courier New");
break;
}
newFont = CreateFontIndirect(&FontRec);
SelectObject(*dc, newFont);
if(*hFont)DeleteObject(*hFont);
*hFont = newFont;
if(!(*hFont)) return false;
}
return RetVal;
}
bool com_Arc(HDC dc, int x1, int y1, int x2, int y2, int quads)
{
int bx, by, ex, ey;
if(x1 > x2) Swap(x1, x2); if(y1 > y2) Swap(y1, y2);
switch (quads) {
case 1:
bx = (x1+x2)>>1; by = y2;
ex = x2; ey = (y1 +y2)>>1;
break;
case 2:
bx = x1; ex = x2; by = ey = (y1 +y2)>>1;
break;
case 3:
bx = (x1+x2)>>1; by = y1;
ex = x2; ey = (y1 +y2)>>1;
break;
case 4:
bx = ex = x2; by = ey = (y1 +y2)>>1;
break;
default: return false;
}
if(Arc(dc, x1, y1, x2, y2, bx, by, ex, ey)) return true;
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Output to windows bitmap
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BitMapWin::BitMapWin(GraphObj *g, HWND hw):anyOutput()
{
HDC dc;
HWND hwndDesk;
memDC = 0L; hgo = 0L; go = g;
dc = GetDC(hwndDesk = GetDesktopWindow());
hres = (double)GetDeviceCaps(dc, LOGPIXELSX);
vres = (double)GetDeviceCaps(dc, LOGPIXELSY);
if(hw) GetClientRect(hw, &DeskRect);
else GetClientRect(hwndDesk, &DeskRect);
Box1.Xmin = DeskRect.left; Box1.Xmax = DeskRect.right;
Box1.Ymin = DeskRect.top; Box1.Ymax = DeskRect.bottom;
scr = CreateCompatibleBitmap(dc, DeskRect.right, DeskRect.bottom);
memDC = CreateCompatibleDC(NULL);
SelectObject(memDC, scr);
ReleaseDC(hwndDesk, dc);
hPen = CreatePen(PS_SOLID, 1, dLineCol = 0x00ffffffL);
hBrush = CreateSolidBrush(dFillCol =dBgCol = 0x00ffffffL);
dPattern = 0L;
if(memDC) {
oldPen = (HPEN)SelectObject(memDC, hPen);
oldBrush = (HBRUSH)SelectObject(memDC, hBrush);
}
else {
oldBrush = 0L;
oldPen = 0L;
}
hFont = 0L;
}
BitMapWin::BitMapWin(int w, int h, double hr, double vr)
{
HDC dc;
HWND hwndDesk;
memDC = 0L; hgo = 0L; go = 0L;
hres = hr; vres = vr;
units = defs.cUnits;
DeskRect.right = w; DeskRect.bottom = h;
DeskRect.left = DeskRect.top = 0;
VPorg.fx = VPorg.fy = 0.0;
dc = GetDC(hwndDesk = GetDesktopWindow());
scr = CreateCompatibleBitmap(dc, DeskRect.right, DeskRect.bottom);
memDC = CreateCompatibleDC(NULL);
ReleaseDC(hwndDesk, dc);
SelectObject(memDC, scr);
hPen = CreatePen(PS_SOLID, 1, dLineCol = 0x00ffffffL);
hBrush = CreateSolidBrush(dFillCol =dBgCol = 0x00ffffffL);
dPattern = 0L;
if(memDC) {
SelectObject(memDC, hPen);
SelectObject(memDC, hBrush);
}
hFont = 0L;
}
BitMapWin::BitMapWin(GraphObj *g):anyOutput()
{
HDC dc;
HWND hwndDesk;
memDC = 0L; hgo = 0L; go = g;
dc = GetDC(hwndDesk = GetDesktopWindow());
hres = vres = 300.0;
units = defs.cUnits;
DeskRect.right = un2ix(go->GetSize(SIZE_GRECT_RIGHT) - go->GetSize(SIZE_GRECT_LEFT));
DeskRect.bottom = un2iy(go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP));
DeskRect.top = DeskRect.left = 0;
VPorg.fy = -co2fiy(go->GetSize(SIZE_GRECT_TOP));
VPorg.fx = -co2fix(go->GetSize(SIZE_GRECT_LEFT));
scr = CreateCompatibleBitmap(dc, DeskRect.right, DeskRect.bottom);
memDC = CreateCompatibleDC(NULL);
SelectObject(memDC, scr);
ReleaseDC(hwndDesk, dc);
hPen = CreatePen(PS_SOLID, 1, dLineCol = 0x00ffffffL);
hBrush = CreateSolidBrush(dFillCol =dBgCol = 0x00ffffffL);
dPattern = 0L;
if(memDC) {
SelectObject(memDC, hPen);
SelectObject(memDC, hBrush);
}
hFont = 0L;
}
BitMapWin::~BitMapWin()
{
if(go) {
go->Command(CMD_CAN_DELETE, 0L, 0L);
}
Undo.KillDisp(this);
if(hgo) delete hgo;
if(hFont) DeleteObject(hFont);
if(scr) DeleteObject(scr);
SelectObject(memDC, oldPen);
SelectObject(memDC, oldBrush);
if(memDC) DeleteDC(memDC);
if(hPen) DeleteObject(hPen);
if(hBrush) DeleteObject(hBrush);
hgo = 0L; hFont = 0L; scr = 0L;
memDC = 0L; hPen = 0L; hBrush = 0L;
}
bool
BitMapWin::SetLine(LineDEF *lDef)
{
int iw;
HPEN newPen;
if(!hPen || lDef->width != LineWidth || lDef->width != LineWidth ||
lDef->pattern != dPattern || lDef->color != dLineCol) {
LineWidth = lDef->width;
iw = iround(un2fix(lDef->width));
dPattern = lDef->pattern;
RLP.finc = 256.0/un2fix(lDef->patlength*8.0);
RLP.fp = 0.0;
if(iLine == iw && dLineCol == lDef->color && hPen) return true;
iLine = iw;
dLineCol = lDef->color;
newPen = CreatePen(PS_SOLID, iw > 0 ? iw : 1, dLineCol);
SelectObject(memDC, newPen);
if(hPen) DeleteObject(hPen);
hPen = newPen;
}
return true;
}
bool
BitMapWin::SetFill(FillDEF *fill)
{
HBRUSH newBrush;
if(!fill) return false;
if((fill->type & 0xff) != FILL_NONE) {
if(!hgo) hgo = new HatchOut(this);
if(hgo) hgo->SetFill(fill);
}
else {
if(hgo) delete hgo;
hgo = NULL;
}
if(dFillCol != fill->color) {
newBrush = CreateSolidBrush(dFillCol = fill->color);
SelectObject(memDC, newBrush);
if(hBrush) DeleteObject(hBrush);
hBrush = newBrush;
}
dFillCol = fill->color;
dFillCol2 = fill->color2;
return true;
}
bool
BitMapWin::SetTextSpec(TextDEF *set)
{
return com_SetTextSpec(set, this, &hFont, &TxtSet, &memDC, isWIN95);
}
bool
BitMapWin::Erase(DWORD Color)
{
HPEN hBGpen, hOldPen;
HBRUSH hBGbrush, hOldBrush;
hBGpen = CreatePen(PS_SOLID, 1, Color);
hBGbrush = CreateSolidBrush(Color);
if(hBGpen && memDC) {
if(hBGbrush) {
hOldBrush = (HBRUSH)SelectObject(memDC, hBGbrush);
hOldPen = (HPEN)SelectObject(memDC, hBGpen);
Rectangle(memDC, 0, 0, DeskRect.right, DeskRect.bottom);
SelectObject(memDC, hOldBrush);
SelectObject(memDC, hOldPen);
DeleteObject(hBGbrush);
DeleteObject(hBGpen);
return true;
}
if(hBGpen) DeleteObject(hBGpen);
}
return false;
}
bool
BitMapWin::CopyBitmap(int x, int y, anyOutput* sr, int sx, int sy,
int sw, int sh, bool invert)
{
BitMapWin *src = (BitMapWin*)sr;
return(0 != BitBlt(memDC, x, y, sw, sh, src->memDC, sx, sy,
invert ? DSTINVERT : SRCCOPY));
}
bool
BitMapWin::oGetTextExtent(char *text, int cb, int *width, int *height)
{
SIZE TextExtent;
double si, csi, d;
if(!text) return false;
if(!GetTextExtentPoint32(memDC, text, cb ? cb : strlen(text), &TextExtent))return false;
if(fabs(TxtSet.RotBL) >0.01) {
si = fabs(sin(TxtSet.RotBL * 0.01745329252)); csi = fabs(cos(TxtSet.RotBL * 0.01745329252));
d = si > csi ? 1.0/si : 1.0/csi;
d = (TextExtent.cx * ((7.0 + d)/8.0));
TextExtent.cx = iround(d);
}
*width = TextExtent.cx; *height = TextExtent.cy;
return true;
}
bool
BitMapWin::oGetPix(int x, int y, DWORD *col)
{
DWORD pix;
if(x >= DeskRect.left && x < DeskRect.right &&
y >= DeskRect.top && y < DeskRect.bottom) {
pix = GetPixel(memDC, x, y);
*col = pix;
return true;
}
else return false;
}
bool
BitMapWin::oDrawIcon(int type, int x, int y)
{
HICON icon = 0L;
switch(type) {
case ICO_INFO:
icon = LoadIcon(0L, IDI_ASTERISK);
break;
case ICO_ERROR:
icon = LoadIcon(0L, IDI_HAND);
break;
case ICO_RLPLOT:
icon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_EVAL));
break;
}
if(icon){
DrawIcon(memDC, x, y, icon);
return true;
}
return false;
}
bool
BitMapWin::oCircle(int x1, int y1, int x2, int y2, char *nam)
{
BOOL RetVal;
RetVal = Ellipse(memDC, x1, y1, x2, y2);
if(RetVal && hgo) return hgo->oCircle(x1, y1, x2, y2);
else if(RetVal) return true;
return false;
}
bool
BitMapWin::oPolyline(POINT * pts, int cp, char *nam)
{
int i;
if(cp < 1) return false;
if (dPattern) {
for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
return true;
}
else {
if(Polyline(memDC, pts, cp))return true;
else return false;
}
}
bool
BitMapWin::oRectangle(int x1, int y1, int x2, int y2, char *name)
{
BOOL RetVal;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -