Rainbow nest

git-svn-id: svn://ultimatepp.org/upp/trunk@3529 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2011-06-13 19:19:08 +00:00
parent b79918ff26
commit 036fd725ec
22 changed files with 6208 additions and 0 deletions

View file

@ -0,0 +1,16 @@
#include <CtrlLib/CtrlLib.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
void ChSysInit()
{
CtrlImg::Reset();
CtrlsImg::Reset();
ChReset();
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,296 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#define LTIMING(x) // RTIMING(x)
void SystemDraw::BeginOp()
{
LTIMING("Begin");
GuiLock __;
Cloff& w = cloff.Add();
w.org = actual_offset;
w.drawingclip = drawingclip;
w.hrgn = CreateRectRgn(0, 0, 0, 0);
ASSERT(w.hrgn);
int q = ::GetClipRgn(handle, w.hrgn);
ASSERT(q >= 0);
if(q == 0) {
DeleteObject(w.hrgn);
w.hrgn = NULL;
}
}
void SystemDraw::OffsetOp(Point p)
{
GuiLock __;
Begin();
actual_offset += p;
drawingclip -= p;
LTIMING("Offset");
SetOrg();
}
bool SystemDraw::ClipOp(const Rect& r)
{
GuiLock __;
Begin();
LTIMING("Clip");
return IntersectClip(r);
}
bool SystemDraw::ClipoffOp(const Rect& r)
{
GuiLock __;
Begin();
LTIMING("Clipoff");
LLOG("ClipoffOp " << r << ", GetClip() = " << GetClip() << ", actual_offset = " << actual_offset);
actual_offset += r.TopLeft();
bool q = IntersectClip(r);
drawingclip -= r.TopLeft();
SetOrg();
LLOG("//ClipoffOp, GetClip() = " << GetClip() << ", actual_offset = " << actual_offset);
return q;
}
void SystemDraw::EndOp()
{
GuiLock __;
LTIMING("End");
ASSERT(cloff.GetCount());
Cloff& w = cloff.Top();
actual_offset = w.org;
drawingclip = w.drawingclip;
::SelectClipRgn(handle, w.hrgn);
SetOrg();
if(w.hrgn)
::DeleteObject(w.hrgn);
cloff.Drop();
}
bool SystemDraw::ExcludeClipOp(const Rect& r)
{
GuiLock __;
#ifdef PLATFORM_WINCE
int q = ExcludeClipRect(handle, r.left, r.top, r.right, r.bottom);
#else
LTIMING("ExcludeClip");
if(r.Contains(drawingclip))
drawingclip = Rect(0, 0, 0, 0);
Rect rr = LPtoDP(r);
HRGN hrgn = ::CreateRectRgnIndirect(rr);
int q = ::ExtSelectClipRgn(handle, hrgn, RGN_DIFF);
ASSERT(q != ERROR);
::DeleteObject(hrgn);
#endif
return q == SIMPLEREGION || q == COMPLEXREGION;
}
bool SystemDraw::IntersectClipOp(const Rect& r)
{
GuiLock __;
#ifdef PLATFORM_WINCE
int q = IntersectClipRect(handle, r.left, r.top, r.right, r.bottom);
#else
LTIMING("Intersect");
drawingclip &= r;
Rect rr = LPtoDP(r);
HRGN hrgn = ::CreateRectRgnIndirect(rr);
int q = ::ExtSelectClipRgn(handle, hrgn, RGN_AND);
ASSERT(q != ERROR);
::DeleteObject(hrgn);
#endif
return q == SIMPLEREGION || q == COMPLEXREGION;
}
bool SystemDraw::IsPaintingOp(const Rect& r) const
{
GuiLock __;
LTIMING("IsPainting");
LLOG("SystemDraw::IsPaintingOp r: " << r);
return ::RectVisible(handle, r);
}
Rect SystemDraw::GetPaintRect() const
{
GuiLock __;
LTIMING("GetPaintRect");
return drawingclip;
}
void SystemDraw::DrawRectOp(int x, int y, int cx, int cy, Color color)
{
GuiLock __;
LTIMING("DrawRect");
LLOG("DrawRect " << RectC(x, y, cx, cy) << ": " << color);
if(IsNull(color)) return;
if(cx <= 0 || cy <= 0) return;
if(color == InvertColor)
::PatBlt(handle, x, y, cx, cy, DSTINVERT);
else {
SetColor(color);
::PatBlt(handle, x, y, cx, cy, PATCOPY);
}
}
void SystemDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
{
GuiLock __;
if(IsNull(width) || IsNull(color)) return;
SetDrawPen(width, color);
::MoveToEx(handle, x1, y1, NULL);
::LineTo(handle, x2, y2);
}
#ifndef PLATFORM_WINCE
void SystemDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count,
const int *counts, int count_count,
int width, Color color, Color doxor)
{
GuiLock __;
ASSERT(count_count > 0 && vertex_count > 0);
if(vertex_count < 2 || IsNull(color))
return;
bool is_xor = !IsNull(doxor);
if(is_xor)
color = Color(color.GetR() ^ doxor.GetR(), color.GetG() ^ doxor.GetG(), color.GetB() ^ doxor.GetB());
if(is_xor)
SetROP2(GetHandle(), R2_XORPEN);
SetDrawPen(width, color);
if(count_count == 1)
::Polyline(GetHandle(), (const POINT *)vertices, vertex_count);
else
::PolyPolyline(GetHandle(), (const POINT *)vertices,
(const dword *)counts, count_count);
if(is_xor)
SetROP2(GetHandle(), R2_COPYPEN);
}
static void DrawPolyPolyPolygonRaw(
SystemDraw& draw, const Point *vertices, int vertex_count,
const int *subpolygon_counts, int subpolygon_count_count,
const int *disjunct_polygon_counts, int disjunct_polygon_count_count)
{
GuiLock __;
for(int i = 0; i < disjunct_polygon_count_count; i++, disjunct_polygon_counts++)
{
int poly = *disjunct_polygon_counts;
int sub = 1;
if(*subpolygon_counts < poly)
if(disjunct_polygon_count_count > 1)
{
const int *se = subpolygon_counts;
int total = 0;
while(total < poly)
total += *se++;
sub = (int)(se - subpolygon_counts);
}
else
sub = subpolygon_count_count;
ASSERT(sizeof(POINT) == sizeof(Point)); // modify algorithm when not
if(sub == 1)
Polygon(draw, (const POINT *)vertices, poly);
else
PolyPolygon(draw, (const POINT *)vertices, subpolygon_counts, sub);
vertices += poly;
subpolygon_counts += sub;
}
}
void SystemDraw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
const int *subpolygon_counts, int subpolygon_count_count,
const int *disjunct_polygon_counts, int disjunct_polygon_count_count,
Color color, int width, Color outline, uint64 pattern, Color doxor)
{
GuiLock __;
if(vertex_count == 0)
return;
bool is_xor = !IsNull(doxor);
HDC hdc = GetHandle();
if(pattern) {
int old_rop = GetROP2(hdc);
HGDIOBJ old_brush = GetCurrentObject(hdc, OBJ_BRUSH);
word wpat[8] = {
(byte)(pattern >> 56), (byte)(pattern >> 48), (byte)(pattern >> 40), (byte)(pattern >> 32),
(byte)(pattern >> 24), (byte)(pattern >> 16), (byte)(pattern >> 8), (byte)(pattern >> 0),
};
HBITMAP bitmap = CreateBitmap(8, 8, 1, 1, wpat);
HBRUSH brush = ::CreatePatternBrush(bitmap);
COLORREF old_bk = GetBkColor(hdc);
COLORREF old_fg = GetTextColor(hdc);
if(!is_xor) {
SetROP2(hdc, R2_MASKPEN);
SelectObject(hdc, brush);
SetTextColor(hdc, Black());
SetBkColor(hdc, White());
SetDrawPen(PEN_NULL, Black);
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
subpolygon_counts, subpolygon_count_count,
disjunct_polygon_counts, disjunct_polygon_count_count);
SetROP2(hdc, R2_MERGEPEN);
SetTextColor(hdc, color);
SetBkColor(hdc, Black());
}
else {
SetROP2(hdc, R2_XORPEN);
SetTextColor(hdc, COLORREF(color) ^ COLORREF(doxor));
SelectObject(hdc, brush);
}
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
subpolygon_counts, subpolygon_count_count,
disjunct_polygon_counts, disjunct_polygon_count_count);
SelectObject(hdc, old_brush);
SetTextColor(hdc, old_fg);
SetBkColor(hdc, old_bk);
SetROP2(hdc, old_rop);
DeleteObject(brush);
DeleteObject(bitmap);
if(!IsNull(outline)) {
SetColor(Null);
SetDrawPen(width, outline);
ASSERT(sizeof(POINT) == sizeof(Point));
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
subpolygon_counts, subpolygon_count_count,
disjunct_polygon_counts, disjunct_polygon_count_count);
}
}
else { // simple fill
SetDrawPen(IsNull(outline) ? PEN_NULL : width, Nvl(outline, Black));
int old_rop2;
if(is_xor) {
color = Color(color.GetR() ^ doxor.GetR(), color.GetG() ^ doxor.GetG(), color.GetB() ^ doxor.GetB());
old_rop2 = SetROP2(hdc, R2_XORPEN);
}
SetColor(color);
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
subpolygon_counts, subpolygon_count_count,
disjunct_polygon_counts, disjunct_polygon_count_count);
if(is_xor)
SetROP2(hdc, old_rop2);
}
}
void SystemDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
{
GuiLock __;
SetDrawPen(width, color);
::Arc(GetHandle(), rc.left, rc.top, rc.right, rc.bottom, start.x, start.y, end.x, end.y);
}
#endif
void SystemDraw::DrawEllipseOp(const Rect& r, Color color, int width, Color pencolor)
{
GuiLock __;
SetColor(color);
SetDrawPen(width, pencolor);
::Ellipse(GetHandle(), r.left, r.top, r.right, r.bottom);
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,46 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
#define LLOG(x)
HFONT GetWin32Font(Font fnt, int angle);
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink,
int n, const int *dx) {
Std(font);
while(n > 30000) {
DrawTextOp(x, y, angle, text, font, ink, 30000, dx);
if(dx)
for(int i = 0; i < 30000; i++)
x += *dx++;
else
x += GetTextSize(text, font, 30000).cx;
n -= 30000;
text += 30000;
}
GuiLock __;
COLORREF cr = GetColor(ink);
if(cr != lastTextColor) {
LLOG("Setting text color: " << ink);
::SetTextColor(handle, lastTextColor = cr);
}
HGDIOBJ orgfont = ::SelectObject(handle, GetWin32Font(font, angle));
int ascent = font.Info().GetAscent();
if(angle) {
double sina, cosa;
Draw::SinCos(angle, sina, cosa);
Size offset;
::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, (const WCHAR *)text, n, dx);
}
else
::ExtTextOutW(handle, x, y + ascent, 0, NULL, (const WCHAR *)text,
n, dx);
::SelectObject(handle, orgfont);
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,467 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#define LTIMING(x) // RTIMING(x)
static COLORREF sLightGray;
Rect SystemDraw::GetVirtualScreenArea()
{
GuiLock __;
return RectC(GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN));
}
dword SystemDraw::GetInfo() const
{
return DATABANDS|(native || !(style & DOTS) ? style|NATIVE : style);
}
Size SystemDraw::GetPageSize() const
{
return native && Dots() ? nativeSize : pageSize;
}
Size SystemDraw::GetNativeDpi() const
{
return Dots() ? nativeDpi : Size(96, 96);
}
#ifndef PLATFORM_WINCE
void Add(LOGPALETTE *pal, int r, int g, int b)
{
pal->palPalEntry[pal->palNumEntries].peRed = min(r, 255);
pal->palPalEntry[pal->palNumEntries].peGreen = min(g, 255);
pal->palPalEntry[pal->palNumEntries].peBlue = min(b, 255);
pal->palPalEntry[pal->palNumEntries++].peFlags = PC_NOCOLLAPSE;
}
HPALETTE GetQlibPalette()
{
static HPALETTE hQlibPalette;
if(hQlibPalette) return hQlibPalette;
SystemDraw::InitColors();
LOGPALETTE *pal = (LOGPALETTE *) new byte[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
pal->palNumEntries = 0;
pal->palVersion = 0x300;
for(int r = 0; r < 6; r++)
for(int g = 0; g < 6; g++)
for(int b = 0; b < 6; b++)
Add(pal, 255 * r / 5, 255 * g / 5, 255 * b / 5);
for(int q = 0; q <= 16; q++)
Add(pal, 16 * q, 16 * q, 16 * q);
Add(pal, GetRValue(sLightGray), GetGValue(sLightGray), GetBValue(sLightGray));
hQlibPalette = CreatePalette(pal);
delete[] pal;
return hQlibPalette;
}
#endif
SystemDraw& GLOBAL_VP(ScreenDraw, ScreenInfo, (true))
HDC ScreenHDC()
{
static HDC hdc;
ONCELOCK {
hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
}
return hdc;
}
static bool _AutoPalette = true;
bool SystemDraw::AutoPalette() { return _AutoPalette; }
void SystemDraw::SetAutoPalette(bool ap) { _AutoPalette = ap; }
COLORREF SystemDraw::GetColor(Color c) const {
COLORREF color = c;
#ifdef PLATFORM_WINCE
return color;
#else
if(!palette)
return color;
static Index<dword> *SColor;
ONCELOCK {
static Index<dword> StaticColor;
StaticColor << RGB(0x00, 0x00, 0x00) << RGB(0x80, 0x00, 0x00) << RGB(0x00, 0x80, 0x00)
<< RGB(0x80, 0x80, 0x00) << RGB(0x00, 0x00, 0x80) << RGB(0x80, 0x00, 0x80)
<< RGB(0x00, 0x80, 0x80) << RGB(0xC0, 0xC0, 0xC0) << RGB(0xC0, 0xDC, 0xC0)
<< RGB(0xA6, 0xCA, 0xF0) << RGB(0xFF, 0xFB, 0xF0) << RGB(0xA0, 0xA0, 0xA4)
<< RGB(0x80, 0x80, 0x80) << RGB(0xFF, 0x00, 0x00) << RGB(0x00, 0xFF, 0x00)
<< RGB(0xFF, 0xFF, 0x00) << RGB(0x00, 0x00, 0xFF) << RGB(0xFF, 0x00, 0xFF)
<< RGB(0x00, 0xFF, 0xFF) << RGB(0xFF, 0xFF, 0xFF);
SColor = &StaticColor;
}
if(color16 || !AutoPalette())
return GetNearestColor(handle, color);
if(SColor->Find(color) >= 0)
return color;
if(color == sLightGray)
return PALETTEINDEX(216 + 17);
int r = GetRValue(color);
int g = GetGValue(color);
int b = GetBValue(color);
return PALETTEINDEX(r == g && g == b ? (r + 8) / 16 + 216
: (r + 25) / 51 * 36 +
(g + 25) / 51 * 6 +
(b + 25) / 51);
#endif
}
void SystemDraw::InitColors()
{
}
void SystemDraw::SetColor(Color color)
{
GuiLock __;
LLOG("SetColor " << color);
if(color != lastColor) {
LLOG("Setting, lastColor:" << FormatIntHex(lastColor.GetRaw())
<< " color:" << FormatIntHex(color.GetRaw()) <<
" GetColor:" << FormatIntHex(GetColor(color)) << " palette:" << palette);
HBRUSH oldBrush = actBrush;
HBRUSH h;
if(!IsNull(color))
h = (HBRUSH) SelectObject(handle, actBrush = CreateSolidBrush(GetColor(color)));
else {
HGDIOBJ empty = GetStockObject(HOLLOW_BRUSH);
h = (HBRUSH) SelectObject(handle, empty);
actBrush = NULL;
}
ASSERT(h);
if(!orgBrush) orgBrush = h;
if(oldBrush) DeleteObject(oldBrush);
lastColor = color;
}
}
void SystemDraw::SetDrawPen(int width, Color color) {
GuiLock __;
if(IsNull(width))
width = PEN_NULL;
if(width != lastPen || color != lastPenColor) {
static int penstyle[] = {
PS_NULL, PS_SOLID, PS_DASH,
#ifndef PLATFORM_WINCE
PS_DOT, PS_DASHDOT, PS_DASHDOTDOT
#endif
};
HPEN oldPen = actPen;
actPen = CreatePen(width < 0 ? penstyle[-width - 1] : PS_SOLID,
width < 0 ? 0 : width, GetColor(color));
HPEN h = (HPEN) SelectObject(handle, actPen);
if(!orgPen) orgPen = h;
if(oldPen) DeleteObject(oldPen);
lastPen = width;
lastPenColor = color;
}
}
void SystemDraw::SetOrg() {
GuiLock __;
#ifdef PLATFORM_WINCE
::SetViewportOrgEx(handle, actual_offset.x, actual_offset.y, 0);
#else
LLOG("SystemDraw::SetOrg: clip = " << GetClip() << ", offset = " << actual_offset);
::SetWindowOrgEx(handle, -actual_offset.x, -actual_offset.y, 0);
LLOG("//SystemDraw::SetOrg: clip = " << GetClip());
#endif
}
#ifndef PLATFORM_WINCE
Point SystemDraw::LPtoDP(Point p) const {
GuiLock __;
::LPtoDP(handle, p, 1);
return p;
}
Point SystemDraw::DPtoLP(Point p) const {
GuiLock __;
::DPtoLP(handle, p, 1);
return p;
}
Rect SystemDraw::LPtoDP(const Rect& r) const {
GuiLock __;
Rect w = r;
::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
return w;
}
Rect SystemDraw::DPtoLP(const Rect& r) const {
GuiLock __;
Rect w = r;
::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
return w;
}
#endif
Size SystemDraw::GetSizeCaps(int i, int j) const {
GuiLock __;
return Size(GetDeviceCaps(handle, i), GetDeviceCaps(handle, j));
}
void SystemDraw::DotsMode()
{
::SetMapMode(handle, MM_ANISOTROPIC);
::SetViewportExtEx(handle, nativeDpi.cx, nativeDpi.cy, NULL);
::SetViewportOrgEx(handle, 0, 0, NULL);
::SetWindowExtEx(handle, 600, 600, NULL);
::SetWindowOrgEx(handle, 0, 0, NULL);
}
void SystemDraw::BeginNative()
{
if(GetPixelsPerInch() != nativeDpi && ++native == 1) {
::SetMapMode(handle, MM_TEXT);
actual_offset_bak = actual_offset;
Native(actual_offset);
SetOrg();
}
}
void SystemDraw::EndNative()
{
if(GetPixelsPerInch() == nativeDpi && --native == 0) {
DotsMode();
actual_offset = actual_offset_bak;
SetOrg();
}
}
int SystemDraw::GetCloffLevel() const
{
return cloff.GetCount();
}
void SystemDraw::LoadCaps() {
GuiLock __;
color16 = false;
palette = (GetDeviceCaps(handle, RASTERCAPS) & RC_PALETTE);
if(palette)
color16 = GetDeviceCaps(handle, SIZEPALETTE) != 256;
nativeSize = pageSize = GetSizeCaps(HORZRES, VERTRES);
nativeDpi = GetSizeCaps(LOGPIXELSX, LOGPIXELSY);
is_mono = GetDeviceCaps(handle, BITSPIXEL) == 1 && GetDeviceCaps(handle, PLANES) == 1;
}
void SystemDraw::Cinit() {
GuiLock __;
lastColor = Color::FromCR(COLORREF(-5));
lastPenColor = Color::FromCR(COLORREF(-5));
lastTextColor = COLORREF(-1);
lastPen = Null;
actBrush = orgBrush = NULL;
actPen = orgPen = NULL;
}
void SystemDraw::Init() {
GuiLock __;
drawingclip = Rect(-(INT_MAX >> 1), -(INT_MAX >> 1), +(INT_MAX >> 1), +(INT_MAX >> 1));
Cinit();
SetBkMode(handle, TRANSPARENT);
::SetTextAlign(handle, TA_BASELINE);
#ifdef PLATFORM_WINCE
actual_offset = Point(0, 0);
#else
::GetViewportOrgEx(handle, actual_offset);
#endif
LoadCaps();
}
void SystemDraw::InitClip(const Rect& clip)
{
drawingclip = clip;
}
void SystemDraw::Reset() {
GuiLock __;
style = GUI;
}
SystemDraw::SystemDraw() {
GuiLock __;
native = 0;
InitColors();
actual_offset = Point(0, 0);
Reset();
handle = NULL;
}
SystemDraw::SystemDraw(HDC hdc) {
GuiLock __;
native = 0;
InitColors();
Reset();
Attach(hdc);
}
void SystemDraw::Unselect0() {
GuiLock __;
if(orgPen) SelectObject(handle, orgPen);
if(orgBrush) SelectObject(handle, orgBrush);
if(actPen) DeleteObject(actPen);
if(actBrush) DeleteObject(actBrush);
Cinit();
}
void SystemDraw::Unselect() {
GuiLock __;
while(cloff.GetCount())
End();
Unselect0();
}
SystemDraw::~SystemDraw() {
GuiLock __;
if(handle)
Unselect();
}
HDC SystemDraw::BeginGdi() {
GuiLock __;
Begin();
return handle;
}
void SystemDraw::EndGdi() {
GuiLock __;
Unselect0();
End();
}
void BackDraw::Create(SystemDraw& w, int cx, int cy) {
ASSERT(w.GetHandle());
GuiLock __;
Destroy();
size.cx = cx;
size.cy = cy;
hbmp = ::CreateCompatibleBitmap(w.GetHandle(), cx, cy);
handle = ::CreateCompatibleDC(w.GetHandle());
ASSERT(hbmp);
ASSERT(handle);
#ifndef PLATFORM_WINCE
if(AutoPalette()) {
::SelectPalette(handle, GetQlibPalette(), FALSE);
::RealizePalette(handle);
}
#endif
hbmpold = (HBITMAP) ::SelectObject(handle, hbmp);
Init();
InitClip(size);
}
void BackDraw::Put(SystemDraw& w, int x, int y) {
GuiLock __;
ASSERT(handle);
LTIMING("BackDraw::Put");
#ifdef PLATFORM_WINCE
::SetViewportOrgEx(handle, 0, 0, 0);
#else
::SetWindowOrgEx(handle, 0, 0, NULL);
#endif
::BitBlt(w, x, y, size.cx, size.cy, *this, 0, 0, SRCCOPY);
}
void BackDraw::Destroy() {
GuiLock __;
if(handle) {
Unselect();
::SelectObject(handle, hbmpold);
::DeleteDC(handle);
::DeleteObject(hbmp);
handle = NULL;
}
}
ScreenDraw::ScreenDraw(bool ic) {
GuiLock __;
#ifdef PLATFORM_WINCE
Attach(CreateDC(NULL, NULL, NULL, NULL));
#else
Attach(ic ? CreateIC("DISPLAY", NULL, NULL, NULL) : CreateDC("DISPLAY", NULL, NULL, NULL));
InitClip(GetVirtualScreenArea());
if(AutoPalette()) {
SelectPalette(handle, GetQlibPalette(), TRUE);
RealizePalette(handle);
}
#endif
}
ScreenDraw::~ScreenDraw() {
GuiLock __;
Unselect();
DeleteDC(handle);
}
#ifndef PLATFORM_WINCE
void PrintDraw::InitPrinter()
{
GuiLock __;
Init();
style = PRINTER|DOTS;
DotsMode();
native = 0;
actual_offset = Point(0, 0);
aborted = false;
pageSize.cx = 600 * nativeSize.cx / nativeDpi.cx;
pageSize.cy = 600 * nativeSize.cy / nativeDpi.cy;
InitClip(pageSize);
}
void PrintDraw::StartPage()
{
GuiLock __;
if(aborted) return;
Unselect();
if(::StartPage(handle) <= 0)
aborted = true;
else
InitPrinter();
}
void PrintDraw::EndPage()
{
GuiLock __;
if(aborted) return;
Unselect();
if(::EndPage(handle) <= 0)
aborted = true;
}
PrintDraw::PrintDraw(HDC hdc, const char *docname)
: SystemDraw(hdc)
{
GuiLock __;
DOCINFO di;
memset(&di, 0, sizeof(di));
di.cbSize = sizeof(di);
String sys_docname = ToSystemCharset(docname);
di.lpszDocName = ~sys_docname;
if(::StartDoc(hdc, &di) <= 0)
aborted = true;
else
InitPrinter();
}
PrintDraw::~PrintDraw() {
GuiLock __;
if(aborted)
::AbortDoc(handle);
else
::EndDoc(handle);
DeleteDC(handle);
handle = NULL;
}
#endif
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,657 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
#include <shellapi.h>
NAMESPACE_UPP
#define LTIMING(x) // RTIMING(x)
bool ImageFallBack
// = true
;
struct Image::Data::SystemData {
LPCSTR cursor_cheat;
HBITMAP hbmp;
HBITMAP hmask;
HBITMAP himg;
RGBA *section;
};
class BitmapInfo32__ {
Buffer<byte> data;
public:
operator BITMAPINFO *() { return (BITMAPINFO *)~data; }
operator BITMAPINFOHEADER *() { return (BITMAPINFOHEADER *)~data; }
BITMAPINFOHEADER *operator->() { return (BITMAPINFOHEADER *)~data; }
BitmapInfo32__(int cx, int cy);
};
BitmapInfo32__::BitmapInfo32__(int cx, int cy)
{
data.Alloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256);
BITMAPINFOHEADER *hi = (BITMAPINFOHEADER *) ~data;;
memset(hi, 0, sizeof(BITMAPINFOHEADER));
hi->biSize = sizeof(BITMAPINFOHEADER);
hi->biPlanes = 1;
#ifdef PLATFORM_WINCE
hi->biBitCount = 32;
hi->biCompression = BI_BITFIELDS;
dword *x = (dword *)(~data + sizeof(BITMAPINFOHEADER));
x[2] = 0xff;
x[1] = 0xff00;
x[0] = 0xff0000;
#else
hi->biBitCount = 32;
hi->biCompression = BI_RGB;
#endif
hi->biSizeImage = 0;
hi->biClrUsed = 0;
hi->biClrImportant = 0;
hi->biWidth = cx;
hi->biHeight = -cy;
}
HBITMAP CreateBitMask(const RGBA *data, Size sz, Size tsz, Size csz, RGBA *ct)
{
GuiLock __;
memset(ct, 0, tsz.cx * tsz.cy * sizeof(RGBA));
int linelen = (tsz.cx + 15) >> 4 << 1;
Buffer<byte> mask(tsz.cy * linelen, 0xff);
byte *m = mask;
RGBA *ty = ct;
const RGBA *sy = data;
for(int y = 0; y < csz.cy; y++) {
const RGBA *s = sy;
RGBA *t = ty;
for(int x = 0; x < csz.cx; x++) {
if(s->a > 128) {
*t = *s;
m[x >> 3] &= ~(0x80 >> (x & 7));
}
else
t->r = t->g = t->b = 0;
t->a = 0;
t++;
s++;
}
m += linelen;
sy += sz.cx;
ty += tsz.cx;
}
return ::CreateBitmap(tsz.cx, tsz.cy, 1, 1, mask);
}
void SetSurface(HDC dc, const Rect& dest, const RGBA *pixels, Size srcsz, Point srcoff)
{
GuiLock __;
BitmapInfo32__ bi(srcsz.cx, srcsz.cy);
::SetDIBitsToDevice(dc, dest.left, dest.top, dest.GetWidth(), dest.GetHeight(),
srcoff.x, -srcoff.y - dest.Height() + srcsz.cy, 0, srcsz.cy, pixels, bi,
DIB_RGB_COLORS);
}
void SetSurface(HDC dc, int x, int y, int cx, int cy, const RGBA *pixels)
{
SetSurface(dc, RectC(x, y, cx, cy), pixels, Size(cx, cy), Point(0, 0));
}
void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels)
{
SetSurface(w.GetHandle(), x, y, cx, cy, pixels);
}
void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff)
{
SetSurface(w.GetHandle(), dest, pixels, psz, poff);
}
class DrawSurface : NoCopy {
int x, y;
Size size;
RGBA *pixels;
HDC dc, dcMem;
HBITMAP hbmp, hbmpOld;
void Init(SystemDraw& w, int x, int y, int cx, int cy);
RGBA* Line(int i) const { ASSERT(i >= 0 && i < size.cy); return (RGBA *)pixels + size.cx * (size.cy - i - 1); }
public:
operator RGBA *() { return pixels; }
Size GetSize() const { return size; }
RGBA *operator[](int i) { return Line(i); }
const RGBA *operator[](int i) const { return Line(i); }
int GetLineDelta() const { return -size.cx; }
DrawSurface(SystemDraw& w, const Rect& r);
DrawSurface(SystemDraw& w, int x, int y, int cx, int cy);
~DrawSurface();
};
void DrawSurface::Init(SystemDraw& w, int _x, int _y, int cx, int cy)
{
GuiLock __;
dc = w.GetHandle();
size = Size(cx, cy);
x = _x;
y = _y;
dcMem = ::CreateCompatibleDC(dc);
BitmapInfo32__ bi(cx, cy);
hbmp = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
hbmpOld = (HBITMAP) ::SelectObject(dcMem, hbmp);
::BitBlt(dcMem, 0, 0, cx, cy, dc, x, y, SRCCOPY);
}
DrawSurface::DrawSurface(SystemDraw& w, const Rect& r)
{
Init(w, r.left, r.top, r.Width(), r.Height());
}
DrawSurface::DrawSurface(SystemDraw& w, int x, int y, int cx, int cy)
{
Init(w, x, y, cx, cy);
}
DrawSurface::~DrawSurface()
{
GuiLock __;
::BitBlt(dc, x, y, size.cx, size.cy, dcMem, 0, 0, SRCCOPY);
::DeleteObject(::SelectObject(dcMem, hbmpOld));
::DeleteDC(dcMem);
}
void Image::Data::SysInitImp()
{
SystemData& sd = Sys();
sd.hbmp = sd.hmask = sd.himg = NULL;
sd.cursor_cheat = NULL;
}
void Image::Data::SysReleaseImp()
{
SystemData& sd = Sys();
if(sd.hbmp) {
GuiLock __;
DeleteObject(sd.hbmp);
ResCount -= !paintonly;
}
if(sd.hmask) {
GuiLock __;
DeleteObject(sd.hmask);
ResCount -= !paintonly;
}
if(sd.himg) {
GuiLock __;
DeleteObject(sd.himg);
ResCount -= !paintonly;
}
sd.himg = sd.hbmp = sd.hmask = NULL;
}
#ifndef PLATFORM_WINCE
typedef BOOL (WINAPI *tAlphaBlend)(HDC hdcDest, int nXOriginDest, int nYOriginDest,
int nWidthDest, int nHeightDest,
HDC hdcSrc, int nXOriginSrc, int nYOriginSrc,
int nWidthSrc, int nHeightSrc, BLENDFUNCTION blendFunction);
static tAlphaBlend fnAlphaBlend()
{
GuiLock __;
static tAlphaBlend pSet;
static bool inited = false;
if(!inited) {
inited = true;
if(HMODULE hDLL = LoadLibrary("msimg32.dll"))
pSet = (tAlphaBlend) GetProcAddress(hDLL, "AlphaBlend");
}
return pSet;
}
#endif
void Image::SetCursorCheat(LPCSTR id)
{
data->Sys().cursor_cheat = id;
}
LPCSTR Image::GetCursorCheat() const
{
return data ? data->Sys().cursor_cheat : NULL;
}
Image::Data::SystemData& Image::Data::Sys() const
{
ASSERT(sizeof(system_buffer) >= sizeof(SystemData));
return *(SystemData *)system_buffer;
}
int Image::Data::GetResCountImp() const
{
SystemData& sd = Sys();
return !!sd.hbmp + !!sd.hmask + !!sd.himg;
}
void Image::Data::CreateHBMP(HDC dc, const RGBA *data)
{
GuiLock __;
SystemData& sd = Sys();
Size sz = buffer.GetSize();
BitmapInfo32__ bi(sz.cx, sz.cy);
HDC dcMem = ::CreateCompatibleDC(dc);
RGBA *pixels;
HBITMAP hbmp32 = CreateDIBSection(dcMem, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
HDC hbmpOld = (HDC) ::SelectObject(dcMem, hbmp32);
memcpy(pixels, data, buffer.GetLength() * sizeof(RGBA));
HDC dcMem2 = ::CreateCompatibleDC(dc);
sd.hbmp = ::CreateCompatibleBitmap(dc, sz.cx, sz.cy);
HBITMAP o2 = (HBITMAP)::SelectObject(dcMem2, sd.hbmp);
::BitBlt(dcMem2, 0, 0, sz.cx, sz.cy, dcMem, 0, 0, SRCCOPY);
::SelectObject(dcMem2, o2);
::DeleteDC(dcMem2);
::SelectObject(dcMem, hbmpOld);
::DeleteObject(hbmp32);
::DeleteDC(dcMem);
ResCount++;
}
void Image::Data::PaintImp(SystemDraw& w, int x, int y, const Rect& src, Color c)
{
GuiLock __;
SystemData& sd = Sys();
ASSERT(!paintonly || IsNull(c));
int max = IsWinNT() ? 250 : 100;
while(ResCount > max) {
Image::Data *l = ResData->GetPrev();
l->SysRelease();
l->Unlink();
}
HDC dc = w.GetHandle();
Size sz = buffer.GetSize();
int len = sz.cx * sz.cy;
Rect sr = src & sz;
Size ssz = sr.Size();
if(sr.IsEmpty())
return;
if(GetKind() == IMAGE_EMPTY)
return;
if(GetKind() == IMAGE_OPAQUE && !IsNull(c)) {
w.DrawRect(x, y, sz.cx, sz.cy, c);
return;
}
if(GetKind() == IMAGE_OPAQUE && paintcount == 0 && sr == Rect(sz) && IsWinNT() && w.IsGui()) {
LTIMING("Image Opaque direct set");
SetSurface(w, x, y, sz.cx, sz.cy, buffer);
paintcount++;
return;
}
Unlink();
LinkAfter(ResData);
if(GetKind() == IMAGE_OPAQUE) {
if(!sd.hbmp) {
LTIMING("Image Opaque create");
CreateHBMP(dc, buffer);
}
LTIMING("Image Opaque blit");
HDC dcMem = ::CreateCompatibleDC(dc);
HBITMAP o = (HBITMAP)::SelectObject(dcMem, sd.hbmp);
::BitBlt(dc, x, y, ssz.cx, ssz.cy, dcMem, sr.left, sr.top, SRCCOPY);
::SelectObject(dcMem, o);
::DeleteDC(dcMem);
PaintOnlyShrink();
return;
}
if(GetKind() == IMAGE_MASK/* || GetKind() == IMAGE_OPAQUE*/) {
HDC dcMem = ::CreateCompatibleDC(dc);
if(!sd.hmask) {
LTIMING("Image Mask create");
Buffer<RGBA> bmp(len);
sd.hmask = CreateBitMask(buffer, sz, sz, sz, bmp);
ResCount++;
if(!sd.hbmp)
CreateHBMP(dc, bmp);
}
LTIMING("Image Mask blt");
HBITMAP o = (HBITMAP)::SelectObject(dcMem, ::CreateCompatibleBitmap(dc, sz.cx, sz.cy));
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dc, x, y, SRCCOPY);
HDC dcMem2 = ::CreateCompatibleDC(dc);
::SelectObject(dcMem2, sd.hmask);
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dcMem2, sr.left, sr.top, SRCAND);
if(IsNull(c)) {
::SelectObject(dcMem2, sd.hbmp);
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dcMem2, sr.left, sr.top, SRCPAINT);
}
else {
HBRUSH ho = (HBRUSH) SelectObject(dcMem, CreateSolidBrush(c));
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dcMem2, sr.left, sr.top, 0xba0b09);
::DeleteObject(::SelectObject(dcMem, ho));
}
::BitBlt(dc, x, y, ssz.cx, ssz.cy, dcMem, 0, 0, SRCCOPY);
::DeleteObject(::SelectObject(dcMem, o));
::DeleteDC(dcMem2);
::DeleteDC(dcMem);
PaintOnlyShrink();
return;
}
#ifndef PLATFORM_WINCE
if(fnAlphaBlend() && IsNull(c) && !ImageFallBack) {
if(!sd.himg) {
LTIMING("Image Alpha create");
BitmapInfo32__ bi(sz.cx, sz.cy);
sd.himg = CreateDIBSection(ScreenHDC(), bi, DIB_RGB_COLORS, (void **)&sd.section, NULL, 0);
ResCount++;
memcpy(sd.section, ~buffer, buffer.GetLength() * sizeof(RGBA));
}
LTIMING("Image Alpha blit");
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255;
bf.AlphaFormat = AC_SRC_ALPHA;
HDC dcMem = ::CreateCompatibleDC(dc);
::SelectObject(dcMem, sd.himg);
fnAlphaBlend()(dc, x, y, ssz.cx, ssz.cy, dcMem, sr.left, sr.top, ssz.cx, ssz.cy, bf);
::DeleteDC(dcMem);
PaintOnlyShrink();
}
else
#endif
{
LTIMING("Image Alpha sw");
DrawSurface sf(w, x, y, ssz.cx, ssz.cy);
RGBA *t = sf;
for(int i = sr.top; i < sr.bottom; i++) {
if(IsNull(c))
AlphaBlendOpaque(t, buffer[i] + sr.left, ssz.cx);
else
AlphaBlendOpaque(t, buffer[i] + sr.left, ssz.cx, c);
t += ssz.cx;
}
}
}
void ImageDraw::Section::Init(int cx, int cy)
{
GuiLock __;
dc = ::CreateCompatibleDC(ScreenHDC());
BitmapInfo32__ bi(cx, cy);
hbmp = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
hbmpOld = (HBITMAP) ::SelectObject(dc, hbmp);
}
ImageDraw::Section::~Section()
{
GuiLock __;
::DeleteObject(::SelectObject(dc, hbmpOld));
::DeleteDC(dc);
}
void ImageDraw::Init()
{
GuiLock __;
rgb.Init(size.cx, size.cy);
a.Init(size.cx, size.cy);
Attach(rgb.dc);
InitClip(size);
alpha.Attach(a.dc);
alpha.InitClip(size);
has_alpha = false;
}
Image ImageDraw::Get(bool pm) const
{
ImageBuffer b(size);
int n = size.cx * size.cy;
memcpy(~b, rgb.pixels, n * sizeof(RGBA));
const RGBA *s = a.pixels;
const RGBA *e = a.pixels + n;
RGBA *t = b;
if(has_alpha) {
while(s < e) {
t->a = s->r;
t++;
s++;
}
if(pm)
Premultiply(b);
b.SetKind(IMAGE_ALPHA);
}
else {
while(s < e) {
t->a = 255;
t++;
s++;
}
b.SetKind(IMAGE_OPAQUE);
}
return b;
}
ImageDraw::operator Image() const
{
return Get(true);
}
Image ImageDraw::GetStraight() const
{
return Get(false);
}
ImageDraw::ImageDraw(Size sz)
{
size = sz;
Init();
}
ImageDraw::ImageDraw(int cx, int cy)
{
size = Size(cx, cy);
Init();
}
ImageDraw::~ImageDraw()
{
Detach();
alpha.Detach();
}
#ifdef PLATFORM_WINCE
Image Image::Arrow() { return Null; }
Image Image::Wait() { return Null; }
Image Image::IBeam() { return Null; }
Image Image::No() { return Null; }
Image Image::SizeAll() { return Null; }
Image Image::SizeHorz() { return Null; }
Image Image::SizeVert() { return Null; }
Image Image::SizeTopLeft() { return Null; }
Image Image::SizeTop() { return Null; }
Image Image::SizeTopRight() { return Null; }
Image Image::SizeLeft() { return Null; }
Image Image::SizeRight() { return Null; }
Image Image::SizeBottomLeft() { return Null; }
Image Image::SizeBottom() { return Null; }
Image Image::SizeBottomRight() { return Null; }
#else
static Image sWin32Icon(HICON icon, bool cursor)
{
GuiLock __;
ICONINFO iconinfo;
if(!icon || !GetIconInfo(icon, &iconinfo))
return Image();
BITMAP bm;
::GetObject((HGDIOBJ)iconinfo.hbmMask, sizeof(BITMAP), (LPVOID)&bm);
HDC dcMem = ::CreateCompatibleDC(NULL);
Size sz(bm.bmWidth, bm.bmHeight);
BitmapInfo32__ bi(sz.cx, sz.cy);
int len = sz.cx * sz.cy;
Buffer<RGBA> mask(len);
::SelectObject(dcMem, iconinfo.hbmColor);
::GetDIBits(dcMem, iconinfo.hbmMask, 0, sz.cy, ~mask, bi, DIB_RGB_COLORS);
ImageBuffer b(sz.cx, iconinfo.hbmColor ? sz.cy : sz.cy / 2);
b.SetHotSpot(Point(iconinfo.xHotspot, iconinfo.yHotspot));
if(iconinfo.hbmColor) {
::SelectObject(dcMem, iconinfo.hbmColor);
::GetDIBits(dcMem, iconinfo.hbmColor, 0, sz.cy, ~b, bi, DIB_RGB_COLORS);
RGBA *s = ~b;
RGBA *e = s + len;
RGBA *m = mask;
while(s < e) {
if(s->a != 255 && s->a != 0) {
Premultiply(b);
goto alpha;
}
s++;
}
s = ~b;
while(s < e) {
s->a = m->r ? 0 : 255;
s++;
m++;
}
}
else {
len /= 2;
RGBA *s = ~b;
RGBA *e = s + len;
RGBA *c = mask + len;
RGBA *m = mask;
while(s < e) {
s->a = (m->r & ~c->r) ? 0 : 255;
s->r = s->g = s->b = (c->r & ~m->r) ? 255 : 0;
s++;
m++;
c++;
}
}
alpha:
::DeleteDC(dcMem);
::DeleteObject(iconinfo.hbmColor);
::DeleteObject(iconinfo.hbmMask);
Image img(b);
::DestroyIcon(icon);
return img;
}
Image Win32IconCursor(LPCSTR id, int iconsize, bool cursor)
{
HICON icon;
if(cursor)
icon = (HICON)LoadCursor(0, id);
else
if(iconsize)
icon = (HICON)LoadImage(GetModuleHandle(NULL), id,
IMAGE_ICON, iconsize, iconsize, LR_DEFAULTCOLOR);
else
icon = LoadIcon(0, id);
Image img = sWin32Icon(icon, cursor);
if(cursor)
img.SetCursorCheat(id);
return img;
}
Image Win32DllIcon(const char *dll, int ii, bool large)
{
HICON icon;
if(ExtractIconEx(dll, ii, large ? &icon : NULL, large ? NULL : &icon, 1) == 1)
return sWin32Icon(icon, false);
return Null;
}
Image Win32Icon(LPCSTR id, int iconsize)
{
return Win32IconCursor(id, iconsize, false);
}
Image Win32Icon(int id, int iconsize)
{
return Win32Icon(MAKEINTRESOURCE(id), iconsize);
}
Image Win32Cursor(LPCSTR id)
{
return Win32IconCursor(id, 0, true);
}
Image Win32Cursor(int id)
{
return Win32Cursor(MAKEINTRESOURCE(id));
}
HICON IconWin32(const Image& img, bool cursor)
{
GuiLock __;
if(img.IsEmpty())
return NULL;
if(cursor) {
LPCSTR id = img.GetCursorCheat();
if(id)
return (HICON)LoadCursor(0, id);
}
Size sz = img.GetSize();
ICONINFO iconinfo;
iconinfo.fIcon = !cursor;
Point p = img.GetHotSpot();
iconinfo.xHotspot = p.x;
iconinfo.yHotspot = p.y;
static Size cursor_size(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
Size tsz = sz;
if(!IsWin2K() && cursor)
tsz = cursor_size;
Size csz = Size(min(tsz.cx, sz.cx), min(tsz.cy, sz.cy));
if(IsWinXP() && !ImageFallBack) {
RGBA *pixels;
BitmapInfo32__ bi(tsz.cx, tsz.cy);
HDC dcMem = ::CreateCompatibleDC(NULL);
iconinfo.hbmColor = ::CreateDIBSection(dcMem, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
iconinfo.hbmMask = ::CreateBitmap(tsz.cx, tsz.cy, 1, 1, NULL);
memset(pixels, 0, tsz.cx * tsz.cy * sizeof(RGBA));
for(int y = 0; y < csz.cy; y++)
memcpy(pixels + y * tsz.cx, img[y], csz.cx * sizeof(RGBA));
::DeleteDC(dcMem);
}
else {
Buffer<RGBA> h(tsz.cx * tsz.cy);
HDC dc = ::GetDC(NULL);
BitmapInfo32__ bi(tsz.cx, tsz.cy);
iconinfo.hbmMask = CreateBitMask(~img, sz, tsz, csz, h);
iconinfo.hbmColor = ::CreateDIBitmap(dc, bi, CBM_INIT, h, bi, DIB_RGB_COLORS);
::ReleaseDC(NULL, dc);
}
HICON icon = ::CreateIconIndirect(&iconinfo);
::DeleteObject(iconinfo.hbmColor);
::DeleteObject(iconinfo.hbmMask);
return icon;
}
#define WCURSOR_(x)\
{ Image m; INTERLOCKED { static Image img = Win32Cursor(x); m = img; } return m; }
Image Image::Arrow() WCURSOR_(IDC_ARROW)
Image Image::Wait() WCURSOR_(IDC_WAIT)
Image Image::IBeam() WCURSOR_(IDC_IBEAM)
Image Image::No() WCURSOR_(IDC_NO)
Image Image::SizeAll() WCURSOR_(IDC_SIZEALL)
Image Image::SizeHorz() WCURSOR_(IDC_SIZEWE)
Image Image::SizeVert() WCURSOR_(IDC_SIZENS)
Image Image::SizeTopLeft() WCURSOR_(IDC_SIZENWSE)
Image Image::SizeTop() WCURSOR_(IDC_SIZENS)
Image Image::SizeTopRight() WCURSOR_(IDC_SIZENESW)
Image Image::SizeLeft() WCURSOR_(IDC_SIZEWE)
Image Image::SizeRight() WCURSOR_(IDC_SIZEWE)
Image Image::SizeBottomLeft() WCURSOR_(IDC_SIZENESW)
Image Image::SizeBottom() WCURSOR_(IDC_SIZENS)
Image Image::SizeBottomRight() WCURSOR_(IDC_SIZENWSE)
Image Image::Cross() WCURSOR_(IDC_CROSS)
Image Image::Hand() WCURSOR_(IDC_HAND)
#endif
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,398 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#if defined(COMPILER_MINGW) && !defined(FLASHW_ALL)
// MINGW headers don't include this in (some versions of) windows
extern "C"{
struct FLASHWINFO {
UINT cbSize;
HWND hwnd;
DWORD dwFlags;
UINT uCount;
DWORD dwTimeout;
};
WINUSERAPI BOOL WINAPI FlashWindowEx(FLASHWINFO*);
}
#define FLASHW_STOP 0
#define FLASHW_CAPTION 0x00000001
#define FLASHW_TRAY 0x00000002
#define FLASHW_ALL (FLASHW_CAPTION | FLASHW_TRAY)
#define FLASHW_TIMER 0x00000004
#define FLASHW_TIMERNOFG 0x0000000C
#endif
void TopWindow::SyncSizeHints() {}
LRESULT TopWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
GuiLock __;
HWND hwnd = GetHWND();
#ifndef PLATFORM_WINCE
bool inloop;
#endif
switch(message) {
#ifndef PLATFORM_WINCE
case WM_QUERYENDSESSION:
inloop = InLoop();
WhenClose();
return inloop ? !InLoop() : !IsOpen();
case WM_ENDSESSION:
EndSession() = true;
PostQuitMessage(0);
return 0;
#endif
case WM_CLOSE:
if(IsEnabled()) {
IgnoreMouseUp();
WhenClose();
}
return 0;
case WM_WINDOWPOSCHANGED:
#ifndef PLATFORM_WINCE
if(IsIconic(hwnd))
state = MINIMIZED;
else
if(IsZoomed(hwnd))
state = MAXIMIZED;
else
#endif
{
state = OVERLAPPED;
overlapped = GetScreenClient(hwnd);
}
Layout();
break;
}
return Ctrl::WindowProc(message, wParam, lParam);
}
void TopWindow::SyncTitle0()
{
GuiLock __;
HWND hwnd = GetHWND();
#ifndef PLATFORM_WINCE
if(hwnd)
if(IsWindowUnicode(hwnd))
::SetWindowTextW(hwnd, (const WCHAR*)~title);
else
#endif
::SetWindowText(hwnd, ToSystemCharset(title.ToString()));
}
void TopWindow::DeleteIco0()
{
GuiLock __;
if(ico)
DestroyIcon(ico);
if(lico)
DestroyIcon(lico);
ico = lico = NULL;
}
void TopWindow::DeleteIco()
{
ICall(THISBACK(DeleteIco0));
}
void TopWindow::SyncCaption0()
{
GuiLock __;
LLOG("SyncCaption");
if(fullscreen)
return;
HWND hwnd = GetHWND();
if(hwnd) {
style = ::GetWindowLong(hwnd, GWL_STYLE);
exstyle = ::GetWindowLong(hwnd, GWL_EXSTYLE);
}
style &= ~(WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_POPUP|WS_DLGFRAME);
exstyle &= ~(WS_EX_TOOLWINDOW|WS_EX_DLGMODALFRAME);
style |= WS_CAPTION;
if(hasdhctrl)
style |= WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
if(minimizebox)
style |= WS_MINIMIZEBOX;
if(maximizebox)
style |= WS_MAXIMIZEBOX;
if(sizeable)
style |= WS_THICKFRAME;
#ifndef PLATFORM_WINCE
if(frameless)
style = (style & ~WS_CAPTION) | WS_POPUP;
else
if(IsNull(icon) && !maximizebox && !minimizebox || noclosebox) {
style |= WS_POPUPWINDOW|WS_DLGFRAME;
exstyle |= WS_EX_DLGMODALFRAME;
if(noclosebox)
style &= ~WS_SYSMENU;
}
else
#endif
style |= WS_SYSMENU;
if(tool)
exstyle |= WS_EX_TOOLWINDOW;
if(fullscreen)
style = WS_POPUP;
if(hwnd) {
::SetWindowLong(hwnd, GWL_STYLE, style);
::SetWindowLong(hwnd, GWL_EXSTYLE, exstyle);
SyncTitle();
if(urgent) {
if(IsForeground()) urgent = false;
FLASHWINFO fi;
memset(&fi, 0, sizeof(fi));
fi.cbSize = sizeof(fi);
fi.hwnd = hwnd;
fi.dwFlags = urgent ? FLASHW_TIMER|FLASHW_ALL : FLASHW_STOP;
FlashWindowEx(&fi);
}
}
DeleteIco();
#ifndef PLATFORM_WINCE //TODO!!!
if(hwnd) {
::SendMessage(hwnd, WM_SETICON, false, (LPARAM)(ico = IconWin32(icon)));
::SendMessage(hwnd, WM_SETICON, true, (LPARAM)(lico = IconWin32(largeicon)));
}
#endif
}
void TopWindow::CenterRect(HWND hwnd, int center)
{
GuiLock __;
SetupRect();
if(hwnd && center == 1 || center == 2) {
Size sz = GetRect().Size();
Rect frmrc(sz);
#ifndef PLATFORM_WINCE
::AdjustWindowRect(frmrc, WS_OVERLAPPEDWINDOW, FALSE);
#endif
Rect r, wr;
wr = Ctrl::GetWorkArea().Deflated(-frmrc.left, -frmrc.top,
frmrc.right - sz.cx, frmrc.bottom - sz.cy);
sz.cx = min(sz.cx, wr.Width());
sz.cy = min(sz.cy, wr.Height());
if(center == 1) {
::GetClientRect(hwnd, r);
if(r.IsEmpty())
r = wr;
else {
Point p = r.TopLeft();
::ClientToScreen(hwnd, p);
r.Offset(p);
}
}
else
r = wr;
Point p = r.CenterPos(sz);
if(p.x + sz.cx > wr.right) p.x = wr.right - sz.cx;
if(p.y + sz.cy > wr.bottom) p.y = wr.bottom - sz.cy;
if(p.x < wr.left) p.x = wr.left;
if(p.y < wr.top) p.y = wr.top;
SetRect(p.x, p.y, sz.cx, sz.cy);
}
}
static HWND trayHWND__;
HWND GetTrayHWND__() { return trayHWND__; }
void SetTrayHWND__(HWND hwnd) { trayHWND__ = hwnd; }
void TopWindow::Open(HWND hwnd)
{
GuiLock __;
if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
DistributeAccessKeys();
UsrLogT(3, "OPEN " + Desc(this));
LLOG("TopWindow::Open, owner HWND = " << FormatIntHex((int)hwnd, 8) << ", Active = " << FormatIntHex((int)::GetActiveWindow(), 8));
IgnoreMouseUp();
SyncCaption();
#ifdef PLATFORM_WINCE
if(!GetRect().IsEmpty())
#endif
if(fullscreen) {
SetRect(GetScreenSize());
Create(hwnd, WS_POPUP, 0, false, SW_SHOWMAXIMIZED, false);
}
else {
CenterRect(hwnd, hwnd && hwnd == GetTrayHWND__() ? center ? 2 : 0 : center);
Create(hwnd, style, exstyle, false, state == OVERLAPPED ? SW_SHOWNORMAL :
state == MINIMIZED ? SW_MINIMIZE :
SW_MAXIMIZE, false);
}
PlaceFocus();
SyncCaption();
FixIcons();
}
void TopWindow::Open(Ctrl *owner)
{
GuiLock __;
LLOG("TopWindow::Open(Ctrl) -> " << UPP::Name(owner));
Open(owner ? owner->GetTopCtrl()->GetHWND() : NULL);
if(IsOpen() && top)
top->owner = owner;
}
void TopWindow::Open()
{
Open(::GetActiveWindow()); // :: needed because of ActiveX controls (to create modal dlgs owned by a HWND)
}
void TopWindow::OpenMain()
{
Open((HWND) NULL);
}
void TopWindow::Minimize(bool effect)
{
state = MINIMIZED;
if(IsOpen())
#ifdef PLATFORM_WINCE
::ShowWindow(GetHWND(), SW_MINIMIZE);
#else
::ShowWindow(GetHWND(), effect ? SW_MINIMIZE : SW_SHOWMINIMIZED);
#endif
}
TopWindow& TopWindow::FullScreen(bool b)
{
fullscreen = b;
HWND hwnd = GetOwnerHWND();
bool pinloop = inloop;
WndDestroy();
Overlap();
SetRect(GetDefaultWindowRect());
Open(hwnd);
inloop = pinloop;
return *this;
}
void TopWindow::Maximize(bool effect)
{
state = MAXIMIZED;
if(IsOpen()) {
::ShowWindow(GetHWND(), effect ? SW_MAXIMIZE : SW_SHOWMAXIMIZED);
SyncCaption();
}
}
void TopWindow::Overlap(bool effect)
{
GuiLock __;
state = OVERLAPPED;
if(IsOpen()) {
::ShowWindow(GetHWND(), effect ? SW_SHOWNORMAL : SW_RESTORE);
SyncCaption();
}
}
TopWindow& TopWindow::Style(dword _style)
{
GuiLock __;
style = _style;
if(GetHWND())
::SetWindowLong(GetHWND(), GWL_STYLE, style);
SyncCaption();
return *this;
}
TopWindow& TopWindow::ExStyle(dword _exstyle)
{
GuiLock __;
exstyle = _exstyle;
if(GetHWND())
::SetWindowLong(GetHWND(), GWL_EXSTYLE, exstyle);
SyncCaption();
return *this;
}
TopWindow& TopWindow::TopMost(bool b, bool stay_top)
{
GuiLock __;
HWND hwnd;
if(hwnd = GetHWND())
SetWindowPos(hwnd, b ? HWND_TOPMOST : (stay_top ? HWND_NOTOPMOST : HWND_BOTTOM),
0,0,0,0,SWP_NOMOVE|SWP_NOSIZE );
return ExStyle(b ? GetExStyle() | WS_EX_TOPMOST : GetExStyle() & ~WS_EX_TOPMOST);
}
bool TopWindow::IsTopMost() const
{
return GetExStyle() & WS_EX_TOPMOST;
}
void TopWindow::GuiPlatformConstruct()
{
style = 0;
exstyle = 0;
ico = lico = NULL;
}
void TopWindow::GuiPlatformDestruct()
{
DeleteIco();
}
void TopWindow::SerializePlacement(Stream& s, bool reminimize)
{
GuiLock __;
#ifndef PLATFORM_WINCE
int version = 0;
s / version;
Rect rect = GetRect();
s % overlapped % rect;
bool mn = state == MINIMIZED;
bool mx = state == MAXIMIZED;
s.Pack(mn, mx);
LLOG("TopWindow::SerializePlacement / " << (s.IsStoring() ? "write" : "read"));
LLOG("minimized = " << mn << ", maximized = " << mx);
LLOG("rect = " << rect << ", overlapped = " << overlapped);
if(s.IsLoading()) {
if(mn) rect = overlapped;
Rect limit = GetWorkArea();
Rect outer = rect;
::AdjustWindowRect(outer, WS_OVERLAPPEDWINDOW, FALSE);
limit.left += rect.left - outer.left;
limit.top += rect.top - outer.top;
limit.right += rect.right - outer.right;
limit.bottom += rect.bottom - outer.bottom;
Size sz = min(rect.Size(), limit.Size());
rect = RectC(
minmax(rect.left, limit.left, limit.right - sz.cx),
minmax(rect.top, limit.top, limit.bottom - sz.cy),
sz.cx, sz.cy);
state = OVERLAPPED;
if(mn && reminimize)
state = MINIMIZED;
if(mx)
state = MAXIMIZED;
if(state == OVERLAPPED)
SetRect(rect);
if(IsOpen()) {
HWND hwnd = GetHWND();
switch(state) {
case MINIMIZED:
if(!IsIconic(hwnd))
::ShowWindow(hwnd, SW_MINIMIZE);
break;
case MAXIMIZED:
if(!IsZoomed(hwnd))
::ShowWindow(hwnd, SW_MAXIMIZE);
break;
default:
if(IsIconic(hwnd) || IsZoomed(hwnd))
::ShowWindow(hwnd, SW_RESTORE);
break;
}
}
}
#endif
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,75 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
SystemDraw& ScreenInfo();
bool ScreenInPaletteMode()
{
return ScreenInfo().PaletteMode();
}
Size GetScreenSize()
{
return ScreenInfo().GetPageSize();
}
HRGN GetFrameRgn(const Rect& rect, int n) {
HRGN rgn = CreateRectRgnIndirect(rect);
Rect r = rect;
r.Deflate(n);
if(r.Width() > 0 && r.Height() > 0) {
HRGN rgnin = CreateRectRgnIndirect(r);
CombineRgn(rgn, rgn, rgnin, RGN_XOR);
DeleteObject(rgnin);
}
return rgn;
}
void DrawDragRect(SystemDraw& w, const Rect& _rect1, const Rect& _rect2, const Rect& _clip, int n, Color color, uint64 pattern)
{
Point o = w.GetOffset();
Rect rect1 = _rect1 + o;
Rect rect2 = _rect2 + o;
Rect clip = _clip + o;
HDC hdc = w.BeginGdi();
word wpat[8] = {
(byte)(pattern >> 56), (byte)(pattern >> 48), (byte)(pattern >> 40), (byte)(pattern >> 32),
(byte)(pattern >> 24), (byte)(pattern >> 16), (byte)(pattern >> 8), (byte)(pattern >> 0),
};
HBITMAP bitmap = CreateBitmap(8, 8, 1, 1, wpat);
HBRUSH brush = ::CreatePatternBrush(bitmap);
DeleteObject(bitmap);
SetTextColor(hdc, color);
SetBkColor(hdc, SColorText());
Point offset;
#ifdef PLATFORM_WINCE
offset = Point(0, 0);
#else
::GetViewportOrgEx(hdc, offset);
#endif
HRGN rgn = GetFrameRgn(rect1 + offset, n);
HRGN rgn2 = GetFrameRgn(rect2 + offset, n);
HRGN cliprgn = CreateRectRgnIndirect(clip + offset);
CombineRgn(rgn, rgn, rgn2, RGN_XOR);
CombineRgn(rgn, rgn, cliprgn, RGN_AND);
SelectClipRgn(hdc, rgn);
Rect r;
GetClipBox(hdc, r);
HBRUSH obrush = (HBRUSH) SelectObject(hdc, brush);
PatBlt(hdc, r.left, r.top, r.Width(), r.Height(), PATINVERT);
SelectObject(hdc, obrush);
SelectClipRgn(hdc, NULL);
DeleteObject(rgn);
DeleteObject(rgn2);
DeleteObject(cliprgn);
ReleaseDC(NULL, hdc);
DeleteObject(brush);
w.EndGdi();
}
END_UPP_NAMESPACE
#endif

385
rainbow/WinAlt/WinAlt.h Normal file
View file

@ -0,0 +1,385 @@
#define GUI_WINALT
NAMESPACE_UPP
class SystemDraw : public Draw {
public:
virtual dword GetInfo() const;
virtual Size GetPageSize() const;
virtual void BeginOp();
virtual void EndOp();
virtual void OffsetOp(Point p);
virtual bool ClipOp(const Rect& r);
virtual bool ClipoffOp(const Rect& r);
virtual bool ExcludeClipOp(const Rect& r);
virtual bool IntersectClipOp(const Rect& r);
virtual bool IsPaintingOp(const Rect& r) const;
virtual Rect GetPaintRect() const;
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color);
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count,
const int *counts, int count_count,
int width, Color color, Color doxor);
virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
const int *subpolygon_counts, int scc,
const int *disjunct_polygon_counts, int dpcc,
Color color, int width, Color outline,
uint64 pattern, Color doxor);
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
Color ink, int n, const int *dx);
virtual Size GetNativeDpi() const;
virtual void BeginNative();
virtual void EndNative();
virtual int GetCloffLevel() const;
private:
Size pageSize;
Size nativeSize;
Size nativeDpi;
bool palette:1;
bool color16:1;
bool is_mono:1;
int native;
friend class ImageDraw;
friend class FontInfo;
friend class Font;
friend void StaticExitDraw_();
Point actual_offset_bak;
struct Cloff : Moveable<Cloff> {
Point org;
HRGN hrgn;
Rect drawingclip;
};
Array<Cloff> cloff;
Rect drawingclip;
COLORREF lastTextColor;
Color lastColor;
HBRUSH orgBrush;
HBRUSH actBrush;
HPEN orgPen;
HPEN actPen;
int lastPen;
Color lastPenColor;
void Unselect0();
void Cinit();
void LoadCaps();
void SetPrinterMode();
void Reset();
void SetOrg();
friend HPALETTE GetQlibPalette();
void DotsMode();
static void InitColors();
friend class BackDraw;
friend class ScreenDraw;
friend class PrintDraw;
protected:
dword style;
HDC handle;
Point actual_offset;
SystemDraw();
void Init();
void InitClip(const Rect& clip);
public:
static Rect GetVirtualScreenArea();
static void SetAutoPalette(bool ap);
static bool AutoPalette();
bool PaletteMode() { return palette; }
static void Flush() { GdiFlush(); }
COLORREF GetColor(Color color) const;
Point GetOffset() const { return actual_offset; }
#ifndef PLATFORM_WINCE
Point LPtoDP(Point p) const;
Point DPtoLP(Point p) const;
Rect LPtoDP(const Rect& r) const;
Rect DPtoLP(const Rect& r) const;
#endif
void SetColor(Color color);
void SetDrawPen(int width, Color color);
Size GetSizeCaps(int i, int j) const;
HDC BeginGdi();
void EndGdi();
HDC GetHandle() { return handle; }
operator HDC() const { return handle; }
void Unselect();
void Attach(HDC ahandle) { handle = ahandle; Init(); }
HDC Detach() { Unselect(); HDC h = handle; handle = NULL; return h; }
SystemDraw(HDC hdc);
virtual ~SystemDraw();
bool CanSetSurface() { return IsGui() && IsWinNT(); }
};
#ifndef PLATFORM_WINCE
class WinMetaFile {
Size size;
HENHMETAFILE hemf;
void Init();
public:
void Attach(HENHMETAFILE emf);
HENHMETAFILE Detach();
void Set(const void *data, dword len);
void Set(const String& data) { Set(~data, data.GetCount()); }
String Get() const;
operator bool() const { return hemf; }
void SetSize(const Size& sz) { size = sz; }
Size GetSize() const { return hemf ? size : Size(0, 0); }
void Clear();
void Paint(Draw& w, const Rect& r) const;
void Paint(Draw& w, int x, int y, int cx, int cy) const;
void Serialize(Stream& s);
void ReadClipboard();
void WriteClipboard() const;
void Load(const char *file) { Set(LoadFile(file)); }
WinMetaFile() { Init(); }
WinMetaFile(HENHMETAFILE hemf);
WinMetaFile(HENHMETAFILE hemf, Size sz);
WinMetaFile(const char *file);
WinMetaFile(void *data, int len);
WinMetaFile(const String& data);
~WinMetaFile() { Clear(); }
HENHMETAFILE GetHEMF() const { return hemf; }
};
class WinMetaFileDraw : public SystemDraw {
Size size;
public:
bool Create(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
bool Create(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
WinMetaFile Close();
WinMetaFileDraw() {}
WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
WinMetaFileDraw(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
~WinMetaFileDraw();
};
void DrawWMF(Draw& w, int x, int y, int cx, int cy, const String& wmf);
void DrawWMF(Draw& w, int x, int y, const String& wmf);
Drawing LoadWMF(const char *path, int cx, int cy);
Drawing LoadWMF(const char *path);
String AsWMF(const Drawing& iw);
#endif
class ScreenDraw : public SystemDraw {
public:
ScreenDraw(bool ic = false);
~ScreenDraw();
};
#ifndef PLATFORM_WINCE
class PrintDraw : public SystemDraw {
public:
virtual void StartPage();
virtual void EndPage();
private:
bool aborted;
void InitPrinter();
public:
PrintDraw(HDC hdc, const char *jobname);
~PrintDraw();
};
#endif
inline bool BitBlt(HDC ddc, Point d, HDC sdc, const Rect& s, dword rop = SRCCOPY)
{ return BitBlt(ddc, d.x, d.y, s.Width(), s.Height(), sdc, s.left, s.top, rop); }
inline bool StretchBlt(HDC ddc, const Rect& r, HDC sdc, const Rect& s, dword rop = SRCCOPY)
{ return StretchBlt(ddc, r.left, r.top, r.Width(), r.Height(), sdc, s.left, s.top, s.Width(), s.Height(), rop); }
inline bool PatBlt(HDC dc, const Rect& r, dword rop = PATCOPY)
{ return PatBlt(dc, r.left, r.top, r.Width(), r.Height(), rop); }
inline void MoveTo(HDC hdc, Point pt) { MoveToEx(hdc, pt.x, pt.y, 0); }
inline void LineTo(HDC hdc, Point pt) { LineTo(hdc, pt.x, pt.y); }
inline void DrawLine(HDC hdc, Point p, Point q) { MoveTo(hdc, p); LineTo(hdc, q); }
inline void DrawLine(HDC hdc, int px, int py, int qx, int qy) { MoveToEx(hdc, px, py, 0); LineTo(hdc, qx, qy); }
#ifndef PLATFORM_WINCE
inline void DrawArc(HDC hdc, const Rect& rc, Point p, Point q){ Arc(hdc, rc.left, rc.top, rc.right, rc.bottom, p.x, p.y, q.x, q.y); }
#endif
inline void DrawCircle(HDC hdc, int x, int y, int radius) { Ellipse(hdc, x - radius, y - radius, x + radius + 1, y + radius + 1); }
inline void DrawCircle(HDC hdc, Point centre, int radius) { DrawCircle(hdc, centre.x, centre.y, radius); }
inline void DrawEllipse(HDC hdc, const Rect& rc) { Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); }
inline void DrawRect(HDC hdc, const Rect& rc) { Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); }
HDC ScreenHDC();
HPALETTE GetQlibPalette();
Image Win32Icon(LPCSTR id, int iconsize = 0);
Image Win32Icon(int id, int iconsize = 0);
Image Win32Cursor(LPCSTR id);
Image Win32Cursor(int id);
HICON IconWin32(const Image& img, bool cursor = false);
Image Win32DllIcon(const char *dll, int ii, bool large);
class BackDraw : public SystemDraw {
public:
virtual bool IsPaintingOp(const Rect& r) const;
protected:
HBITMAP hbmpold;
HBITMAP hbmp;
Size size;
Draw *painting;
Point painting_offset;
public:
void Put(SystemDraw& w, int x, int y);
void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); }
void Create(SystemDraw& w, int cx, int cy);
void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); }
void Destroy();
void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; }
BackDraw();
~BackDraw();
};
class ImageDraw : public SystemDraw {
Size size;
struct Section {
HDC dc;
HBITMAP hbmp, hbmpOld;
RGBA *pixels;
void Init(int cx, int cy);
~Section();
};
Section rgb;
Section a;
SystemDraw alpha;
bool has_alpha;
void Init();
Image Get(bool pm) const;
public:
Draw& Alpha();
operator Image() const;
Image GetStraight() const;
ImageDraw(Size sz);
ImageDraw(int cx, int cy);
~ImageDraw();
};
END_UPP_NAMESPACE
#define GUIPLATFORM_KEYCODES_INCLUDE "Win32Keys.h"
#define GUIPLATFORM_CTRL_TOP_DECLS \
HWND hwnd; \
UDropTarget *dndtgt; \
#define GUIPLATFORM_CTRL_DECLS_INCLUDE "Win32Ctrl.h"
#define GUIPLATFORM_PASTECLIP_DECLS \
UDropTarget *dt; \
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE "Win32Top.h"
NAMESPACE_UPP
inline unsigned GetHashValue(const HWND& hwnd)
{
return (unsigned)(intptr_t)hwnd;
}
END_UPP_NAMESPACE
#ifdef PLATFORM_WIN32
#ifndef PLATFORM_WINCE
#include <ShellAPI.h>
#endif
#endif
NAMESPACE_UPP
class PrinterJob {
NilDraw nil;
Vector<int> pages;
public:
Draw& GetDraw() { return nil; }
operator Draw&() { return GetDraw(); }
const Vector<int>& GetPages() const { return pages; }
int operator[](int i) const { return 0; }
int GetPageCount() const { return 0; }
bool Execute() { return false; }
PrinterJob& Landscape(bool b = true) { return *this; }
PrinterJob& MinMaxPage(int minpage, int maxpage) { return *this; }
PrinterJob& PageCount(int n) { return *this; }
PrinterJob& CurrentPage(int currentpage) { return *this; }
PrinterJob& Name(const char *_name) { return *this; }
PrinterJob(const char *name = NULL) {}
~PrinterJob() {}
};
END_UPP_NAMESPACE
#define GUIPLATFORM_INCLUDE_AFTER <WinAlt/WinAltGuiA.h>

19
rainbow/WinAlt/WinAlt.upp Normal file
View file

@ -0,0 +1,19 @@
file
WinAlt.h,
WinAltGuiA.h,
WinAltKeys.h,
DrawOpWinAlt.cpp,
DrawTextWinAlt.cpp,
DrawWinAlt.cpp,
ImageWinAlt.cpp,
UtilWinAlt.cpp,
WinAltCtrl.h,
WinAltCtrl.cpp,
TopWinAlt.cpp,
WinAltTop.h,
WinAltClip.cpp,
WinAltDnD.cpp,
WinAltProc.cpp,
WinAltWnd.cpp,
ChSysInit.cpp;

View file

@ -0,0 +1,521 @@
#include <CtrlCore/CtrlCore.h>
#include <plugin/bmp/bmp.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
VectorMap<int, ClipData>& sClipMap()
{
static VectorMap<int, ClipData> x;
return x;
}
extern HWND utilityHWND;
int GetClipboardFormatCode(const char *format_id)
{
GuiLock ___;
int x = (int)(intptr_t)format_id;
if(x >= 0 && x < 65535)
return x;
String fmt = format_id;
if(fmt == "text")
return CF_TEXT;
if(fmt == "wtext")
return CF_UNICODETEXT;
if(fmt == "dib")
return CF_DIB;
if(fmt == "files")
return CF_HDROP;
static StaticMutex m;
Mutex::Lock __(m);
static VectorMap<String, int> format_map;
int f = format_map.Find(format_id);
if(f < 0) {
f = format_map.GetCount();
format_map.Add(format_id,
#ifdef PLATFORM_WINCE
::RegisterClipboardFormat(ToSystemCharset(format_id))
#else
::RegisterClipboardFormat(format_id)
#endif
);
}
return format_map[f];
}
void ClipboardLog(const char *txt)
{
#ifdef flagCHECKCLIPBOARD
FileAppend f(GetExeDirFile("clip.log"));
f << txt << "\n";
#endif
}
void ClipboardError(const char *txt)
{
#ifdef flagCHECKCLIPBOARD
String s = txt;
s << "\n" << GetLastErrorMessage();
MessageBox(::GetActiveWindow(), s, "Clipboard error", MB_ICONSTOP | MB_OK | MB_APPLMODAL);
ClipboardLog(String().Cat() << s << " ERROR");
#endif
}
String FromWin32CF(int cf);
void ClipboardError(const char *txt, int format)
{
#ifdef flagCHECKCLIPBOARD
ClipboardError(String().Cat() << txt << ' ' << FromWin32CF(format));
#endif
}
bool ClipboardOpen()
{
// Win32 has serious race condition problem with clipboard; system or other apps open it
// right after we close it thus blocking us to send more formats
// So the solution is to wait and retry... (mirek, 2011-01-09)
int delay = 5;
for(int i = 0; i < 5; i++) {
if(OpenClipboard(utilityHWND))
return true;
Sleep(delay += delay);
}
return false;
}
void ClearClipboard()
{
GuiLock __;
sClipMap().Clear();
#ifdef flagCHECKCLIPBOARD
DeleteFile(GetExeDirFile("clip.log"));
#endif
ClipboardLog("* ClearClipboard");
if(ClipboardOpen()) {
if(!EmptyClipboard())
ClipboardError("EmptyClipboard ERROR");
if(!CloseClipboard())
ClipboardError("CloseClipboard ERROR");
}
#ifdef flagCHECKCLIPBOARD
else {
ClipboardError("OpenClipboard ERROR");
}
#endif
}
void SetClipboardRaw(int format, const byte *data, int length)
{
GuiLock __;
HANDLE handle = NULL;
ClipboardLog("* SetClipboardRaw");
if(data) {
handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, length + 2);
byte *ptr;
if(!handle) {
ClipboardLog("GlobalAlloc ERROR");
return;
}
if(!(ptr = (byte *)GlobalLock(handle))) {
ClipboardLog("GlobalLock ERROR");
GlobalFree(handle);
return;
}
memcpy(ptr, data, length);
ptr[length] = 0;
ptr[length + 1] = 0;
GlobalUnlock(handle);
}
if(!SetClipboardData(format, handle)) {
ClipboardError("SetCliboardData", format);
LLOG("SetClipboardData error: " << GetLastErrorMessage());
GlobalFree(handle);
}
}
void AppendClipboard(int format, const byte *data, int length)
{
GuiLock __;
ClipboardLog("* AppendClipboard");
if(ClipboardOpen()) {
SetClipboardRaw(format, data, length);
if(!CloseClipboard())
ClipboardError("CloseClipboard", format);
}
else
ClipboardError("OpenClipboard", format);
}
void AppendClipboard(const char *format, const byte *data, int length)
{
GuiLock __;
Vector<String> f = Split(format, ';');
for(int i = 0; i < f.GetCount(); i++)
AppendClipboard(GetClipboardFormatCode(f[i]), data, length);
}
void AppendClipboard(const char *format, const String& data)
{
GuiLock __;
AppendClipboard(format, data, data.GetLength());
}
void AppendClipboard(const char *format, const Value& data, String (*render)(const Value&))
{
GuiLock __;
Vector<String> f = Split(format, ';');
for(int i = 0; i < f.GetCount(); i++) {
int c = GetClipboardFormatCode(f[i]);
sClipMap().GetAdd(c) = ClipData(data, render);
AppendClipboard(c, NULL, 0);
}
}
void Ctrl::RenderFormat(int format)
{
GuiLock __;
int q = sClipMap().Find(format);
if(q >= 0) {
String s = sClipMap()[q].Render();
SetClipboardRaw(format, s, s.GetLength());
}
}
void Ctrl::RenderAllFormats()
{
GuiLock __;
if(sClipMap().GetCount() && OpenClipboard(utilityHWND)) {
for(int i = 0; i < sClipMap().GetCount(); i++)
RenderFormat(sClipMap().GetKey(i));
CloseClipboard();
}
}
void Ctrl::DestroyClipboard()
{
GuiLock __;
sClipMap().Clear();
}
String ReadClipboard(const char *format)
{
GuiLock __;
if(!OpenClipboard(NULL))
return Null;
HGLOBAL hmem = GetClipboardData(GetClipboardFormatCode(format));
if(hmem == 0) {
CloseClipboard();
return Null;
}
const byte *src = (const byte *)GlobalLock(hmem);
ASSERT(src);
int length = (int)GlobalSize(hmem);
if(length < 0) {
CloseClipboard();
return Null;
}
String out(src, length);
GlobalUnlock(hmem);
CloseClipboard();
return out;
}
void AppendClipboardText(const String& s)
{
#ifdef PLATFORM_WINCE
AppendClipboardUnicodeText(s.ToWString());
#else
AppendClipboard("text", ToSystemCharset(s));
#endif
}
void AppendClipboardUnicodeText(const WString& s)
{
#ifndef PLATFORM_WINCE
AppendClipboardText(s.ToString());
#endif
AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength());
}
const char *ClipFmtsText()
{
return "wtext;text";
}
String GetString(PasteClip& clip)
{
GuiLock __;
if(clip.Accept("wtext")) {
String s = ~clip;
return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString();
}
if(clip.IsAvailable("text"))
return ~clip;
return Null;
}
WString GetWString(PasteClip& clip)
{
GuiLock __;
if(clip.Accept("wtext")) {
String s = ~clip;
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
}
if(clip.IsAvailable("text"))
return (~clip).ToWString();
return Null;
}
bool AcceptText(PasteClip& clip)
{
return clip.Accept(ClipFmtsText());
}
static String sText(const Value& data)
{
return data;
}
static String sWText(const Value& data)
{
return Unicode__(WString(data));
}
void Append(VectorMap<String, ClipData>& data, const String& text)
{
data.GetAdd("text", ClipData(text, sText));
data.GetAdd("wtext", ClipData(text, sWText));
}
void Append(VectorMap<String, ClipData>& data, const WString& text)
{
data.GetAdd("text", ClipData(text, sText));
data.GetAdd("wtext", ClipData(text, sWText));
}
String GetTextClip(const WString& text, const String& fmt)
{
if(fmt == "text")
return text.ToString();
if(fmt == "wtext")
return Unicode__(text);
return Null;
}
String GetTextClip(const String& text, const String& fmt)
{
if(fmt == "text")
return text;
if(fmt == "wtext")
return Unicode__(text.ToWString());
return Null;
}
String ReadClipboardText()
{
#ifdef PLATFORM_WINCE
return ReadClipboardUnicodeText().ToString();
#else
String s = ReadClipboard((const char *)CF_TEXT);
return String(s, (int)strlen(~s));
#endif
}
WString ReadClipboardUnicodeText()
{
String s = ReadClipboard((const char *)CF_UNICODETEXT);
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
}
bool IsClipboardAvailable(const char *id)
{
return ::IsClipboardFormatAvailable(GetClipboardFormatCode(id));
}
bool IsClipboardAvailableText()
{
return IsClipboardAvailable((const char *)CF_TEXT);
}
const char *ClipFmtsImage()
{
static const char *q;
ONCELOCK {
static String s = "dib;" + ClipFmt<Image>();
q = s;
}
return q;
}
bool AcceptImage(PasteClip& clip)
{
GuiLock __;
return clip.Accept(ClipFmtsImage());
}
Image GetImage(PasteClip& clip)
{
GuiLock __;
Image m;
if(Accept<Image>(clip)) {
LoadFromString(m, ~clip);
if(!m.IsEmpty())
return m;
}
if(clip.Accept("dib")) {
String data = ~clip;
if((unsigned)data.GetCount() < sizeof(BITMAPINFO)) return Null;
BITMAPINFO *lpBI = (BITMAPINFO *)~data;
BITMAPINFOHEADER& hdr = lpBI->bmiHeader;
byte *bits = (byte *)lpBI + hdr.biSize;
if(hdr.biBitCount <= 8)
bits += (hdr.biClrUsed ? hdr.biClrUsed : 1 << hdr.biBitCount) * sizeof(RGBQUAD);
if(hdr.biBitCount >= 16 || hdr.biBitCount == 32) {
if(hdr.biCompression == 3)
bits += 12;
if(hdr.biClrUsed != 0)
bits += hdr.biClrUsed * sizeof(RGBQUAD);
}
int h = abs((int)hdr.biHeight);
ImageDraw iw(hdr.biWidth, h);
::StretchDIBits(iw.GetHandle(),
0, 0, hdr.biWidth, h,
0, 0, hdr.biWidth, h,
bits, lpBI, DIB_RGB_COLORS, SRCCOPY);
return iw;
}
return Null;
}
Image ReadClipboardImage()
{
GuiLock __;
PasteClip d = Ctrl::Clipboard();
return GetImage(d);
}
String sDib(const Value& image)
{
Image img = image;
BITMAPINFOHEADER header;
Zero(header);
header.biSize = sizeof(header);
header.biWidth = img.GetWidth();
header.biHeight = -img.GetHeight();
header.biBitCount = 32;
header.biPlanes = 1;
header.biCompression = BI_RGB;
StringBuffer b(sizeof(header) + 4 * img.GetLength());
byte *p = (byte *)~b;
memcpy(p, &header, sizeof(header));
memcpy(p + sizeof(header), ~img, 4 * img.GetLength());
return b;
}
String sImage(const Value& image)
{
Image img = image;
return StoreAsString(const_cast<Image&>(img));
}
String GetImageClip(const Image& img, const String& fmt)
{
GuiLock __;
if(img.IsEmpty()) return Null;
if(fmt == "dib")
return sDib(img);
if(fmt == ClipFmt<Image>())
return sImage(img);
return Null;
}
void AppendClipboardImage(const Image& img)
{
GuiLock __;
if(img.IsEmpty()) return;
AppendClipboard(ClipFmt<Image>(), img, sImage);
AppendClipboard("dib", img, sDib);
}
bool AcceptFiles(PasteClip& clip)
{
if(clip.Accept("files")) {
clip.SetAction(DND_COPY);
return true;
}
return false;
}
bool IsAvailableFiles(PasteClip& clip)
{
return clip.IsAvailable("files");
}
struct sDROPFILES {
DWORD offset;
POINT dummy;
BOOL dummy2;
BOOL unicode;
};
Vector<String> GetFiles(PasteClip& clip)
{
GuiLock __;
Vector<String> f;
String data = clip;
if((unsigned)data.GetCount() < sizeof(sDROPFILES) + 2)
return f;
const sDROPFILES *df = (const sDROPFILES *)~data;
const char *s = ((const char *)df + df->offset);
if(df->unicode) {
const wchar *ws = (wchar *)s;
while(*ws) {
WString fn;
while(*ws)
fn.Cat(*ws++);
f.Add(fn.ToString());
ws++;
}
}
else
while(*s) {
String fn;
while(*s)
fn.Cat(*s++);
f.Add(fn.ToString());
s++;
}
return f;
}
bool Has(UDropTarget *dt, const char *fmt);
String Get(UDropTarget *dt, const char *fmt);
bool PasteClip::IsAvailable(const char *fmt) const
{
if(this == &Ctrl::Selection())
return false;
return dt ? UPP::Has(dt, fmt) : IsClipboardAvailable(fmt);
}
String PasteClip::Get(const char *fmt) const
{
if(this == &Ctrl::Selection())
return Null;
return dt ? UPP::Get(dt, fmt) : ReadClipboard(fmt);
}
void PasteClip::GuiPlatformConstruct()
{
dt = NULL;
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,157 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
#define LLOG(x) // DLOG(x)
NAMESPACE_UPP
void Ctrl::GuiPlatformConstruct()
{
activex = false;
isdhctrl = false;
}
void Ctrl::GuiPlatformDestruct()
{
}
void Ctrl::GuiPlatformRemove()
{
}
void Ctrl::GuiPlatformGetTopRect(Rect& r) const
{
if(activex)
r = GetWndScreenRect();
}
bool Ctrl::GuiPlatformRefreshFrameSpecial(const Rect& r)
{
if(isdhctrl) {
InvalidateRect(((DHCtrl *)this)->GetHWND(), r, false);
return true;
}
return false;
}
bool Ctrl::GuiPlatformSetFullRefreshSpecial()
{
return isdhctrl;
}
void Ctrl::PaintCaret(SystemDraw& w)
{
}
String GuiPlatformGetKeyDesc(dword key)
{
static struct {
dword key;
const char *name;
} nkey[] = {
{ 0x100c0, "[`]" }, { 0x100bd, "[-]" }, { 0x100bb, "[=]" }, { 0x100dc, "[\\]" },
{ 0x100db, "[[]" }, { 0x100dd, "[]]" },
{ 0x100ba, "[;]" }, { 0x100de, "[']" },
{ 0x100bc, "[,]" }, { 0x100be, "[.]" }, { 0x100bf, "[/]" },
{ 0, NULL }
};
for(int i = 0; nkey[i].key; i++)
if(nkey[i].key == key)
return nkey[i].name;
return Null;
}
void Ctrl::GuiPlatformSelection(PasteClip&)
{
}
void GuiPlatformAdjustDragImage(ImageBuffer&)
{
}
bool GuiPlatformHasSizeGrip()
{
return true;
}
void GuiPlatformGripResize(TopWindow *q)
{
HWND hwnd = q->GetHWND();
Point p = GetMousePos() - q->GetRect().TopLeft();
if(hwnd) {
::SendMessage(hwnd, WM_SYSCOMMAND, 0xf008, MAKELONG(p.x, p.y));
::SendMessage(hwnd, WM_LBUTTONUP, 0, MAKELONG(p.x, p.y));
}
}
Color GuiPlatformGetScreenPixel(int x, int y)
{
HDC sdc = GetWindowDC(0);
Color c = Color::FromCR(GetPixel(sdc, x, y));
ReleaseDC(0, sdc);
return c;
}
void GuiPlatformAfterMenuPopUp()
{
}
void Ctrl::SetCaret(int x, int y, int cx, int cy)
{
GuiLock __;
caretx = x;
carety = y;
caretcx = cx;
caretcy = cy;
SyncCaret();
}
void Ctrl::SyncCaret() {
GuiLock __;
Rect cr;
cr.Clear();
if(focusCtrl && focusCtrl->IsVisible()) {
bool inframe = focusCtrl->InFrame();
cr = focusCtrl->GetScreenView();
cr = RectC(focusCtrl->caretx + cr.left, focusCtrl->carety + cr.top,
focusCtrl->caretcx, focusCtrl->caretcy) & cr;
for(Ctrl *q = focusCtrl->GetParent(); q; q = q->GetParent()) {
cr &= inframe ? q->GetScreenRect() : q->GetScreenView();
inframe = q->InFrame();
}
}
if(focusCtrl != caretCtrl || cr != caretRect) {
LLOG("Do SyncCaret focusCtrl: " << UPP::Name(focusCtrl)
<< ", caretCtrl: " << UPP::Name(caretCtrl)
<< ", cr: " << cr);
WndDestroyCaret();
if(focusCtrl && !cr.IsEmpty())
focusCtrl->GetTopCtrl()->WndCreateCaret(cr);
caretCtrl = focusCtrl;
caretRect = cr;
}
}
String Ctrl::Name() const {
GuiLock __;
#ifdef CPU_64
String s = String(typeid(*this).name()) + " : 0x" + FormatIntHex(this);
#else
String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this);
#endif
if(IsChild())
s << "(parent " << String(typeid(*parent).name()) << ")";
else
s << Format("(hwnd 0x%x)", (int)(intptr_t) GetHWND());
return s;
}
void Ctrl::WndCreateCaret(const Rect& cr)
{
ICall(THISBACK1(WndCreateCaret0, cr));
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,68 @@
//$ class Ctrl {
private:
bool activex:1;
bool isdhctrl:1;
static void WndDestroyCaret();
void WndCreateCaret0(const Rect& cr);
void WndCreateCaret(const Rect& cr);
static bool PeekMsg(MSG& msg);
static LRESULT CALLBACK UtilityProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static void RenderFormat(int format);
static void RenderAllFormats();
static void DestroyClipboard();
public:
static Event ExitLoopEvent;
static bool& EndSession();
static bool IsEndSession() { return EndSession(); }
static HINSTANCE hInstance;
protected:
static HCURSOR hCursor;
static VectorMap< HWND, Ptr<Ctrl> >& Windows();
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static Event OverwatchEndSession;
static HWND OverwatchHWND;
static HANDLE OverwatchThread;
static LRESULT CALLBACK OverwatchWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static DWORD WINAPI Win32OverwatchThread(LPVOID);
static Rect GetScreenClient(HWND hwnd);
struct CreateBox;
void Create0(CreateBox *cr);
void Create(HWND parent, DWORD style, DWORD exstyle, bool savebits, int show, bool dropshadow);
Image DoMouse(int e, Point p, int zd = 0);
static void sProcessMSG(MSG& msg);
static Vector<Callback> hotkey;
friend void sSetCursor(Ctrl *ctrl, const Image& m);
public:
virtual void NcCreate(HWND hwnd);
virtual void NcDestroy();
virtual void PreDestroy();
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
HWND GetHWND() const { return parent ? NULL : top ? top->hwnd : NULL; }
HWND GetOwnerHWND() const;
static Ctrl *CtrlFromHWND(HWND hwnd);
Ctrl& ActiveX(bool ax = true) { activex = ax; return *this; }
Ctrl& NoActiveX() { return ActiveX(false); }
bool IsActiveX() const { return activex; }
void PopUpHWND(HWND hwnd, bool savebits = true, bool activate = true, bool dropshadow = false,
bool topmost = false);
static void InitWin32(HINSTANCE hinst);
static void ExitWin32();
static void GuiFlush() { ::GdiFlush(); }
//$ };

View file

@ -0,0 +1,542 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
int GetClipboardFormatCode(const char *format_id);
int ToWin32CF(const char *s)
{
return GetClipboardFormatCode(s);
}
String FromWin32CF(int cf)
{
GuiLock __;
if(cf == CF_TEXT)
return "text";
if(cf == CF_UNICODETEXT)
return "wtext";
if(cf == CF_DIB)
return "dib";
#ifndef PLATFORM_WINCE
if(cf == CF_HDROP)
return "files";
#endif
char h[256];
GetClipboardFormatNameA(cf, h, 255);
return h;
}
FORMATETC ToFORMATETC(const char *s)
{
FORMATETC fmtetc;
fmtetc.cfFormat = ToWin32CF(s);
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.ptd = NULL;
fmtetc.tymed = TYMED_HGLOBAL;
return fmtetc;
}
String AsString(POINTL p)
{
return String().Cat() << "[" << p.x << ", " << p.y << "]";
}
struct UDropTarget : public IDropTarget {
ULONG rc;
LPDATAOBJECT data;
Ptr<Ctrl> ctrl;
Index<String> fmt;
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragLeave)();
STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
void DnD(POINTL p, bool drop, DWORD *effect, DWORD keys);
void FreeData();
void Repeat();
void EndDrag();
String Get(const char *fmt) const;
UDropTarget() { rc = 1; data = NULL; }
~UDropTarget();
};
bool Has(UDropTarget *dt, const char *fmt)
{
return dt->fmt.Find(fmt) >= 0;
}
String Get(UDropTarget *dt, const char *fmt)
{
return dt->Get(fmt);
}
STDMETHODIMP UDropTarget::QueryInterface(REFIID iid, void ** ppv)
{
if(iid == IID_IUnknown || iid == IID_IDropTarget) {
*ppv = this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
String UDropTarget::Get(const char *fmt) const
{
FORMATETC fmtetc = ToFORMATETC(fmt);
STGMEDIUM s;
if(data->GetData(&fmtetc, &s) == S_OK && s.tymed == TYMED_HGLOBAL) {
char *val = (char *)GlobalLock(s.hGlobal);
String data(val, (int)GlobalSize(s.hGlobal));
GlobalUnlock(s.hGlobal);
ReleaseStgMedium(&s);
return data;
}
return Null;
}
void UDropTarget::DnD(POINTL pl, bool drop, DWORD *effect, DWORD keys)
{
GuiLock __;
LLOG("DnD effect: " << *effect);
dword e = *effect;
*effect = DROPEFFECT_NONE;
if(!ctrl)
return;
PasteClip d;
d.dt = this;
d.paste = drop;
d.accepted = false;
d.allowed = 0;
d.action = 0;
if(e & DROPEFFECT_COPY) {
LLOG("DnD DROPEFFECT_COPY");
d.allowed = DND_COPY;
d.action = DND_COPY;
}
if(e & DROPEFFECT_MOVE) {
LLOG("DnD DROPEFFECT_MOVE");
d.allowed |= DND_MOVE;
if(Ctrl::GetDragAndDropSource())
d.action = DND_MOVE;
}
LLOG("DnD keys & MK_CONTROL:" << (keys & MK_CONTROL));
if((keys & MK_CONTROL) && (d.allowed & DND_COPY))
d.action = DND_COPY;
if((keys & (MK_ALT|MK_SHIFT)) && (d.allowed & DND_MOVE))
d.action = DND_MOVE;
ctrl->DnD(Point(pl.x, pl.y), d);
if(d.IsAccepted()) {
LLOG("DnD accepted, action: " << (int)d.action);
if(d.action == DND_MOVE)
*effect = DROPEFFECT_MOVE;
if(d.action == DND_COPY)
*effect = DROPEFFECT_COPY;
}
}
void UDropTarget::Repeat()
{
Ctrl::DnDRepeat();
}
STDMETHODIMP UDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
GuiLock __;
LLOG("DragEnter " << pt);
data = pDataObj;
data->AddRef();
fmt.Clear();
IEnumFORMATETC *fe;
if(!ctrl || pDataObj->EnumFormatEtc(DATADIR_GET, &fe) != NOERROR) {
*pdwEffect = DROPEFFECT_NONE;
return NOERROR;
}
FORMATETC fmtetc;
while(fe->Next(1, &fmtetc, 0) == S_OK) {
fmt.FindAdd(FromWin32CF(fmtetc.cfFormat));
if(fmtetc.ptd)
CoTaskMemFree(fmtetc.ptd);
}
fe->Release();
DnD(pt, false, pdwEffect, grfKeyState);
return NOERROR;
}
STDMETHODIMP UDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
LLOG("DragOver " << pt << " keys: " << grfKeyState);
DnD(pt, false, pdwEffect, grfKeyState);
return NOERROR;
}
void UDropTarget::FreeData()
{
if(data) {
data->Release();
data = NULL;
}
}
void UDropTarget::EndDrag()
{
Ctrl::DnDLeave();
}
STDMETHODIMP UDropTarget::DragLeave()
{
LLOG("DragLeave");
EndDrag();
FreeData();
return NOERROR;
}
STDMETHODIMP UDropTarget::Drop(LPDATAOBJECT, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
LLOG("Drop");
if(Ctrl::GetDragAndDropSource())
Ctrl::OverrideCursor(Null);
DnD(pt, true, pdwEffect, grfKeyState);
EndDrag();
FreeData();
return NOERROR;
}
UDropTarget::~UDropTarget()
{
if(data) data->Release();
EndDrag();
}
// --------------------------------------------------------------------------------------------
Ptr<Ctrl> sDnDSource;
Ctrl * Ctrl::GetDragAndDropSource()
{
return sDnDSource;
}
struct UDataObject : public IDataObject {
ULONG rc;
dword effect;
VectorMap<String, ClipData> data;
STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(GetData)(FORMATETC *fmtetc, STGMEDIUM *medium);
STDMETHOD(GetDataHere)(FORMATETC *, STGMEDIUM *);
STDMETHOD(QueryGetData)(FORMATETC *fmtetc);
STDMETHOD(GetCanonicalFormatEtc)(FORMATETC *, FORMATETC *pformatetcOut);
STDMETHOD(SetData)(FORMATETC *fmtetc, STGMEDIUM *medium, BOOL release);
STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ief);
STDMETHOD(DAdvise)(FORMATETC *, DWORD, IAdviseSink *, DWORD *);
STDMETHOD(DUnadvise)(DWORD);
STDMETHOD(EnumDAdvise)(LPENUMSTATDATA *);
UDataObject() { rc = 1; effect = 0; }
};
struct UEnumFORMATETC : public IEnumFORMATETC {
ULONG rc;
int ii;
UDataObject *data;
STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(Next)(ULONG n, FORMATETC *fmtetc, ULONG *fetched);
STDMETHOD(Skip)(ULONG n);
STDMETHOD(Reset)(void);
STDMETHOD(Clone)(IEnumFORMATETC **newEnum);
UEnumFORMATETC() { ii = 0; rc = 1; }
~UEnumFORMATETC() { data->Release(); }
};
struct UDropSource : public IDropSource {
ULONG rc;
Image no, move, copy;
STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState);
STDMETHOD(GiveFeedback)(DWORD dwEffect);
UDropSource() { rc = 1; }
};
STDMETHODIMP UDataObject::QueryInterface(REFIID iid, void ** ppv)
{
if(iid == IID_IUnknown || iid == IID_IDataObject) {
*ppv = this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
void SetMedium(STGMEDIUM *medium, const String& data)
{
int sz = data.GetCount();
HGLOBAL hData = GlobalAlloc(0, sz + 4);
if (hData) {
char *ptr = (char *) GlobalLock(hData);
memcpy(ptr, ~data, sz);
memset(ptr + sz, 0, 4);
GlobalUnlock(hData);
medium->tymed = TYMED_HGLOBAL;
medium->hGlobal = hData;
medium->pUnkForRelease = 0;
}
}
STDMETHODIMP UDataObject::GetData(FORMATETC *fmtetc, STGMEDIUM *medium)
{
String fmt = FromWin32CF(fmtetc->cfFormat);
ClipData *s = data.FindPtr(fmt);
if(s) {
String q = s->Render();
SetMedium(medium, q.GetCount() ? q : sDnDSource ? sDnDSource->GetDropData(fmt) : String());
return S_OK;
}
return DV_E_FORMATETC;
}
STDMETHODIMP UDataObject::GetDataHere(FORMATETC *, STGMEDIUM *)
{
return DV_E_FORMATETC;
}
STDMETHODIMP UDataObject::QueryGetData(FORMATETC *fmtetc)
{
return data.Find(FromWin32CF(fmtetc->cfFormat)) >= 0 ? S_OK : DV_E_FORMATETC;
}
STDMETHODIMP UDataObject::GetCanonicalFormatEtc(FORMATETC *, FORMATETC *pformatetcOut)
{
pformatetcOut->ptd = NULL;
return E_NOTIMPL;
}
#ifdef PLATFORM_WINCE
static int CF_PERFORMEDDROPEFFECT = RegisterClipboardFormat(_T("Performed DropEffect"));
#else
static int CF_PERFORMEDDROPEFFECT = RegisterClipboardFormat("Performed DropEffect");
#endif
STDMETHODIMP UDataObject::SetData(FORMATETC *fmtetc, STGMEDIUM *medium, BOOL release)
{
if(fmtetc->cfFormat == CF_PERFORMEDDROPEFFECT && medium->tymed == TYMED_HGLOBAL) {
DWORD *val = (DWORD*)GlobalLock(medium->hGlobal);
effect = *val;
GlobalUnlock(medium->hGlobal);
if(release)
ReleaseStgMedium(medium);
return S_OK;
}
return E_NOTIMPL;
}
STDMETHODIMP UDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ief)
{
UEnumFORMATETC *ef = new UEnumFORMATETC;
ef->data = this;
AddRef();
*ief = ef;
return S_OK;
}
STDMETHODIMP UDataObject::DAdvise(FORMATETC *, DWORD, IAdviseSink *, DWORD *)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP UDataObject::DUnadvise(DWORD)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP UDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP UEnumFORMATETC::QueryInterface(REFIID riid, void FAR* FAR* ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IEnumFORMATETC) {
*ppvObj = this;
AddRef();
return NOERROR;
}
*ppvObj = NULL;
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP UEnumFORMATETC::Next(ULONG n, FORMATETC *t, ULONG *fetched) {
if(t == NULL)
return E_INVALIDARG;
if(fetched) *fetched = 0;
while(ii < data->data.GetCount() && n > 0) {
if(fetched) (*fetched)++;
n--;
*t++ = ToFORMATETC(data->data.GetKey(ii++));
}
return n ? S_FALSE : NOERROR;
}
STDMETHODIMP UEnumFORMATETC::Skip(ULONG n) {
ii += n;
if(ii >= data->data.GetCount())
return S_FALSE;
return NOERROR;
}
STDMETHODIMP UEnumFORMATETC::Reset()
{
ii = 0;
return NOERROR;
}
STDMETHODIMP UEnumFORMATETC::Clone(IEnumFORMATETC **newEnum)
{
if(newEnum == NULL)
return E_INVALIDARG;
UEnumFORMATETC *ef = new UEnumFORMATETC;
ef->data = data;
data->AddRef();
ef->ii = ii;
*newEnum = ef;
return NOERROR;
}
STDMETHODIMP UDropSource::QueryInterface(REFIID riid, void **ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDropSource) {
*ppvObj = this;
AddRef();
return NOERROR;
}
*ppvObj = NULL;
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP UDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
{
if(fEscapePressed)
return DRAGDROP_S_CANCEL;
else
if(!(grfKeyState & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)))
return DRAGDROP_S_DROP;
Ctrl::ProcessEvents();
return NOERROR;
}
STDMETHODIMP UDropSource::GiveFeedback(DWORD dwEffect)
{
LLOG("GiveFeedback");
Image m = IsNull(move) ? copy : move;
if((dwEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY) {
LLOG("GiveFeedback COPY");
if(!IsNull(copy)) m = copy;
}
else
if((dwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE) {
LLOG("GiveFeedback MOVE");
if(!IsNull(move)) m = move;
}
else
m = no;
Ctrl::OverrideCursor(m);
Ctrl::SetMouseCursor(m);
return S_OK;
}
Image MakeDragImage(const Image& arrow, Image sample);
Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample)
{
if(IsWin2K())
return MakeDragImage(arrow, sample);
else
return arrow98;
}
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
const VectorMap<String, ClipData>& data)
{
UDataObject *obj = new UDataObject;
obj->data <<= data;
if(fmts) {
Vector<String> f = Split(fmts, ';');
for(int i = 0; i < f.GetCount(); i++)
obj->data.GetAdd(f[i]);
}
UDropSource *dsrc = new UDropSource;
DWORD result = 0;
Image m = Ctrl::OverrideCursor(CtrlCoreImg::DndMove());
dsrc->no = MakeDragImage(CtrlCoreImg::DndNone(), CtrlCoreImg::DndNone98(), sample);
if(actions & DND_COPY)
dsrc->copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), CtrlCoreImg::DndCopy98(), sample);
if(actions & DND_MOVE)
dsrc->move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMove(), CtrlCoreImg::DndMove98(), sample);
sDnDSource = this;
int level = LeaveGMutexAll();
HRESULT r = DoDragDrop(obj, dsrc,
(actions & DND_COPY ? DROPEFFECT_COPY : 0) |
(actions & DND_MOVE ? DROPEFFECT_MOVE : 0), &result);
EnterGMutex(level);
DWORD re = obj->effect;
obj->Release();
dsrc->Release();
OverrideCursor(m);
SyncCaret();
CheckMouseCtrl();
KillRepeat();
sDnDSource = NULL;
if(r == DRAGDROP_S_DROP) {
if(((result | re) & DROPEFFECT_MOVE) == DROPEFFECT_MOVE && (actions & DND_MOVE))
return DND_MOVE;
if(((result | re) & DROPEFFECT_COPY) == DROPEFFECT_COPY && (actions & DND_COPY))
return DND_COPY;
}
return DND_NONE;
}
void ReleaseUDropTarget(UDropTarget *dt)
{
dt->Release();
}
UDropTarget *NewUDropTarget(Ctrl *ctrl)
{
UDropTarget *dt = new UDropTarget;
dt->ctrl = ctrl;
return dt;
}
void Ctrl::SetSelectionSource(const char *fmts) {}
END_UPP_NAMESPACE
#endif

358
rainbow/WinAlt/WinAltGui.h Normal file
View file

@ -0,0 +1,358 @@
#define GUI_WINALT
NAMESPACE_UPP
class SystemDraw : public Draw {
public:
virtual dword GetInfo() const;
virtual Size GetPageSize() const;
virtual void BeginOp();
virtual void EndOp();
virtual void OffsetOp(Point p);
virtual bool ClipOp(const Rect& r);
virtual bool ClipoffOp(const Rect& r);
virtual bool ExcludeClipOp(const Rect& r);
virtual bool IntersectClipOp(const Rect& r);
virtual bool IsPaintingOp(const Rect& r) const;
virtual Rect GetPaintRect() const;
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color);
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count,
const int *counts, int count_count,
int width, Color color, Color doxor);
virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
const int *subpolygon_counts, int scc,
const int *disjunct_polygon_counts, int dpcc,
Color color, int width, Color outline,
uint64 pattern, Color doxor);
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
Color ink, int n, const int *dx);
virtual Size GetNativeDpi() const;
virtual void BeginNative();
virtual void EndNative();
virtual int GetCloffLevel() const;
private:
Size pageSize;
Size nativeSize;
Size nativeDpi;
bool palette:1;
bool color16:1;
bool is_mono:1;
int native;
friend class ImageDraw;
friend class FontInfo;
friend class Font;
friend void StaticExitDraw_();
Point actual_offset_bak;
struct Cloff : Moveable<Cloff> {
Point org;
HRGN hrgn;
Rect drawingclip;
};
Array<Cloff> cloff;
Rect drawingclip;
COLORREF lastTextColor;
Color lastColor;
HBRUSH orgBrush;
HBRUSH actBrush;
HPEN orgPen;
HPEN actPen;
int lastPen;
Color lastPenColor;
void Unselect0();
void Cinit();
void LoadCaps();
void SetPrinterMode();
void Reset();
void SetOrg();
friend HPALETTE GetQlibPalette();
void DotsMode();
static void InitColors();
friend class BackDraw;
friend class ScreenDraw;
friend class PrintDraw;
protected:
dword style;
HDC handle;
Point actual_offset;
SystemDraw();
void Init();
void InitClip(const Rect& clip);
public:
static Rect GetVirtualScreenArea();
static void SetAutoPalette(bool ap);
static bool AutoPalette();
bool PaletteMode() { return palette; }
static void Flush() { GdiFlush(); }
COLORREF GetColor(Color color) const;
Point GetOffset() const { return actual_offset; }
#ifndef PLATFORM_WINCE
Point LPtoDP(Point p) const;
Point DPtoLP(Point p) const;
Rect LPtoDP(const Rect& r) const;
Rect DPtoLP(const Rect& r) const;
#endif
void SetColor(Color color);
void SetDrawPen(int width, Color color);
Size GetSizeCaps(int i, int j) const;
HDC BeginGdi();
void EndGdi();
HDC GetHandle() { return handle; }
operator HDC() const { return handle; }
void Unselect();
void Attach(HDC ahandle) { handle = ahandle; Init(); }
HDC Detach() { Unselect(); HDC h = handle; handle = NULL; return h; }
SystemDraw(HDC hdc);
virtual ~SystemDraw();
bool CanSetSurface() { return IsGui() && IsWinNT(); }
};
#ifndef PLATFORM_WINCE
class WinMetaFile {
Size size;
HENHMETAFILE hemf;
void Init();
public:
void Attach(HENHMETAFILE emf);
HENHMETAFILE Detach();
void Set(const void *data, dword len);
void Set(const String& data) { Set(~data, data.GetCount()); }
String Get() const;
operator bool() const { return hemf; }
void SetSize(const Size& sz) { size = sz; }
Size GetSize() const { return hemf ? size : Size(0, 0); }
void Clear();
void Paint(Draw& w, const Rect& r) const;
void Paint(Draw& w, int x, int y, int cx, int cy) const;
void Serialize(Stream& s);
void ReadClipboard();
void WriteClipboard() const;
void Load(const char *file) { Set(LoadFile(file)); }
WinMetaFile() { Init(); }
WinMetaFile(HENHMETAFILE hemf);
WinMetaFile(HENHMETAFILE hemf, Size sz);
WinMetaFile(const char *file);
WinMetaFile(void *data, int len);
WinMetaFile(const String& data);
~WinMetaFile() { Clear(); }
HENHMETAFILE GetHEMF() const { return hemf; }
};
class WinMetaFileDraw : public SystemDraw {
Size size;
public:
bool Create(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
bool Create(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
WinMetaFile Close();
WinMetaFileDraw() {}
WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
WinMetaFileDraw(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
~WinMetaFileDraw();
};
void DrawWMF(Draw& w, int x, int y, int cx, int cy, const String& wmf);
void DrawWMF(Draw& w, int x, int y, const String& wmf);
Drawing LoadWMF(const char *path, int cx, int cy);
Drawing LoadWMF(const char *path);
String AsWMF(const Drawing& iw);
#endif
class ScreenDraw : public SystemDraw {
public:
ScreenDraw(bool ic = false);
~ScreenDraw();
};
#ifndef PLATFORM_WINCE
class PrintDraw : public SystemDraw {
public:
virtual void StartPage();
virtual void EndPage();
private:
bool aborted;
void InitPrinter();
public:
PrintDraw(HDC hdc, const char *jobname);
~PrintDraw();
};
#endif
inline bool BitBlt(HDC ddc, Point d, HDC sdc, const Rect& s, dword rop = SRCCOPY)
{ return BitBlt(ddc, d.x, d.y, s.Width(), s.Height(), sdc, s.left, s.top, rop); }
inline bool StretchBlt(HDC ddc, const Rect& r, HDC sdc, const Rect& s, dword rop = SRCCOPY)
{ return StretchBlt(ddc, r.left, r.top, r.Width(), r.Height(), sdc, s.left, s.top, s.Width(), s.Height(), rop); }
inline bool PatBlt(HDC dc, const Rect& r, dword rop = PATCOPY)
{ return PatBlt(dc, r.left, r.top, r.Width(), r.Height(), rop); }
inline void MoveTo(HDC hdc, Point pt) { MoveToEx(hdc, pt.x, pt.y, 0); }
inline void LineTo(HDC hdc, Point pt) { LineTo(hdc, pt.x, pt.y); }
inline void DrawLine(HDC hdc, Point p, Point q) { MoveTo(hdc, p); LineTo(hdc, q); }
inline void DrawLine(HDC hdc, int px, int py, int qx, int qy) { MoveToEx(hdc, px, py, 0); LineTo(hdc, qx, qy); }
#ifndef PLATFORM_WINCE
inline void DrawArc(HDC hdc, const Rect& rc, Point p, Point q){ Arc(hdc, rc.left, rc.top, rc.right, rc.bottom, p.x, p.y, q.x, q.y); }
#endif
inline void DrawCircle(HDC hdc, int x, int y, int radius) { Ellipse(hdc, x - radius, y - radius, x + radius + 1, y + radius + 1); }
inline void DrawCircle(HDC hdc, Point centre, int radius) { DrawCircle(hdc, centre.x, centre.y, radius); }
inline void DrawEllipse(HDC hdc, const Rect& rc) { Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); }
inline void DrawRect(HDC hdc, const Rect& rc) { Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); }
HDC ScreenHDC();
HPALETTE GetQlibPalette();
Image Win32Icon(LPCSTR id, int iconsize = 0);
Image Win32Icon(int id, int iconsize = 0);
Image Win32Cursor(LPCSTR id);
Image Win32Cursor(int id);
HICON IconWin32(const Image& img, bool cursor = false);
Image Win32DllIcon(const char *dll, int ii, bool large);
class BackDraw : public SystemDraw {
public:
virtual bool IsPaintingOp(const Rect& r) const;
protected:
HBITMAP hbmpold;
HBITMAP hbmp;
Size size;
Draw *painting;
Point painting_offset;
public:
void Put(SystemDraw& w, int x, int y);
void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); }
void Create(SystemDraw& w, int cx, int cy);
void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); }
void Destroy();
void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; }
BackDraw();
~BackDraw();
};
class ImageDraw : public SystemDraw {
Size size;
struct Section {
HDC dc;
HBITMAP hbmp, hbmpOld;
RGBA *pixels;
void Init(int cx, int cy);
~Section();
};
Section rgb;
Section a;
SystemDraw alpha;
bool has_alpha;
void Init();
Image Get(bool pm) const;
public:
Draw& Alpha();
operator Image() const;
Image GetStraight() const;
ImageDraw(Size sz);
ImageDraw(int cx, int cy);
~ImageDraw();
};
END_UPP_NAMESPACE
#define GUIPLATFORM_KEYCODES_INCLUDE "Win32Keys.h"
#define GUIPLATFORM_CTRL_TOP_DECLS \
HWND hwnd; \
UDropTarget *dndtgt; \
#define GUIPLATFORM_CTRL_DECLS_INCLUDE "Win32Ctrl.h"
#define GUIPLATFORM_PASTECLIP_DECLS \
UDropTarget *dt; \
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE "Win32Top.h"
NAMESPACE_UPP
inline unsigned GetHashValue(const HWND& hwnd)
{
return (unsigned)(intptr_t)hwnd;
}
END_UPP_NAMESPACE
#ifdef PLATFORM_WIN32
#ifndef PLATFORM_WINCE
#include <ShellAPI.h>
#endif
#endif
#define GUIPLATFORM_INCLUDE_AFTER "Win32GuiA.h"

103
rainbow/WinAlt/WinAltGuiA.h Normal file
View file

@ -0,0 +1,103 @@
class ViewDraw : public SystemDraw {
public:
ViewDraw(Ctrl *ctrl);
~ViewDraw();
protected:
HWND hwnd;
};
Vector<WString>& coreCmdLine__();
Vector<WString> SplitCmdLine__(const char *cmd);
#ifdef PLATFORM_WINCE
#define GUI_APP_MAIN \
void GuiMainFn_();\
\
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int nCmdShow) \
{ \
UPP::Ctrl::InitWin32(hInstance); \
UPP::coreCmdLine__() = UPP::SplitCmdLine__(UPP::FromSystemCharset(lpCmdLine)); \
UPP::AppInitEnvironment__(); \
GuiMainFn_(); \
UPP::Ctrl::CloseTopCtrls(); \
UPP::UsrLog("---------- About to delete this log..."); \
UPP::DeleteUsrLog(); \
UPP::Ctrl::ExitWin32(); \
UPP::AppExit__(); \
return UPP::GetExitCode(); \
} \
\
void GuiMainFn_()
#else
#define GUI_APP_MAIN \
void GuiMainFn_();\
\
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow) \
{ \
UPP::Ctrl::InitWin32(hInstance); \
UPP::coreCmdLine__() = UPP::SplitCmdLine__(UPP::FromSystemCharset(lpCmdLine)); \
UPP::AppInitEnvironment__(); \
GuiMainFn_(); \
UPP::Ctrl::CloseTopCtrls(); \
UPP::UsrLog("---------- About to delete this log..."); \
UPP::DeleteUsrLog(); \
UPP::Ctrl::ExitWin32(); \
UPP::AppExit__(); \
return UPP::GetExitCode(); \
} \
\
void GuiMainFn_()
#define DLL_APP_MAIN \
void _DllMainAppInit(); \
\
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpReserved) \
{ \
if(fdwReason == DLL_PROCESS_ATTACH) { \
Ctrl::InitWin32(AppGetHandle()); \
AppInitEnvironment__(); \
_DllMainAppInit(); \
} \
else \
if(fdwReason == DLL_PROCESS_DETACH) { \
Ctrl::ExitWin32(); \
} \
return true; \
} \
\
void _DllMainAppInit()
#endif
#ifndef PLATFORM_WINCE
class DHCtrl : public Ctrl {
public:
virtual void State(int reason);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual void NcCreate(HWND hwnd);
virtual void NcDestroy();
private:
void OpenHWND();
void SyncHWND();
protected:
void CloseHWND();
HWND hwnd;
public:
HWND GetHWND() { return hwnd; }
// void Refresh() { InvalidateRect(GetHWND(), NULL, false); }
DHCtrl();
~DHCtrl();
};
#endif

109
rainbow/WinAlt/WinAltKeys.h Normal file
View file

@ -0,0 +1,109 @@
K_BACK = VK_BACK + K_DELTA,
K_BACKSPACE = VK_BACK + K_DELTA,
K_TAB = 9,
K_SPACE = 32,
K_RETURN = 13,
K_ENTER = K_RETURN,
K_SHIFT_KEY = VK_SHIFT + K_DELTA,
K_CTRL_KEY = VK_CONTROL + K_DELTA,
K_ALT_KEY = VK_MENU + K_DELTA,
K_CAPSLOCK = VK_CAPITAL + K_DELTA,
K_ESCAPE = VK_ESCAPE + K_DELTA,
K_PRIOR = VK_PRIOR + K_DELTA,
K_PAGEUP = VK_PRIOR + K_DELTA,
K_NEXT = VK_NEXT + K_DELTA,
K_PAGEDOWN = VK_NEXT + K_DELTA,
K_END = VK_END + K_DELTA,
K_HOME = VK_HOME + K_DELTA,
K_LEFT = VK_LEFT + K_DELTA,
K_UP = VK_UP + K_DELTA,
K_RIGHT = VK_RIGHT + K_DELTA,
K_DOWN = VK_DOWN + K_DELTA,
K_INSERT = VK_INSERT + K_DELTA,
K_DELETE = VK_DELETE + K_DELTA,
K_NUMPAD0 = VK_NUMPAD0 + K_DELTA,
K_NUMPAD1 = VK_NUMPAD1 + K_DELTA,
K_NUMPAD2 = VK_NUMPAD2 + K_DELTA,
K_NUMPAD3 = VK_NUMPAD3 + K_DELTA,
K_NUMPAD4 = VK_NUMPAD4 + K_DELTA,
K_NUMPAD5 = VK_NUMPAD5 + K_DELTA,
K_NUMPAD6 = VK_NUMPAD6 + K_DELTA,
K_NUMPAD7 = VK_NUMPAD7 + K_DELTA,
K_NUMPAD8 = VK_NUMPAD8 + K_DELTA,
K_NUMPAD9 = VK_NUMPAD9 + K_DELTA,
K_MULTIPLY = VK_MULTIPLY + K_DELTA,
K_ADD = VK_ADD + K_DELTA,
K_SEPARATOR = VK_SEPARATOR + K_DELTA,
K_SUBTRACT = VK_SUBTRACT + K_DELTA,
K_DECIMAL = VK_DECIMAL + K_DELTA,
K_DIVIDE = VK_DIVIDE + K_DELTA,
K_SCROLL = VK_SCROLL + K_DELTA,
K_F1 = VK_F1 + K_DELTA,
K_F2 = VK_F2 + K_DELTA,
K_F3 = VK_F3 + K_DELTA,
K_F4 = VK_F4 + K_DELTA,
K_F5 = VK_F5 + K_DELTA,
K_F6 = VK_F6 + K_DELTA,
K_F7 = VK_F7 + K_DELTA,
K_F8 = VK_F8 + K_DELTA,
K_F9 = VK_F9 + K_DELTA,
K_F10 = VK_F10 + K_DELTA,
K_F11 = VK_F11 + K_DELTA,
K_F12 = VK_F12 + K_DELTA,
K_A = 'A' + K_DELTA,
K_B = 'B' + K_DELTA,
K_C = 'C' + K_DELTA,
K_D = 'D' + K_DELTA,
K_E = 'E' + K_DELTA,
K_F = 'F' + K_DELTA,
K_G = 'G' + K_DELTA,
K_H = 'H' + K_DELTA,
K_I = 'I' + K_DELTA,
K_J = 'J' + K_DELTA,
K_K = 'K' + K_DELTA,
K_L = 'L' + K_DELTA,
K_M = 'M' + K_DELTA,
K_N = 'N' + K_DELTA,
K_O = 'O' + K_DELTA,
K_P = 'P' + K_DELTA,
K_Q = 'Q' + K_DELTA,
K_R = 'R' + K_DELTA,
K_S = 'S' + K_DELTA,
K_T = 'T' + K_DELTA,
K_U = 'U' + K_DELTA,
K_V = 'V' + K_DELTA,
K_W = 'W' + K_DELTA,
K_X = 'X' + K_DELTA,
K_Y = 'Y' + K_DELTA,
K_Z = 'Z' + K_DELTA,
K_0 = '0' + K_DELTA,
K_1 = '1' + K_DELTA,
K_2 = '2' + K_DELTA,
K_3 = '3' + K_DELTA,
K_4 = '4' + K_DELTA,
K_5 = '5' + K_DELTA,
K_6 = '6' + K_DELTA,
K_7 = '7' + K_DELTA,
K_8 = '8' + K_DELTA,
K_9 = '9' + K_DELTA,
K_CTRL_LBRACKET = K_CTRL|219|K_DELTA,
K_CTRL_RBRACKET = K_CTRL|221|K_DELTA,
K_CTRL_MINUS = K_CTRL|0xbd|K_DELTA,
K_CTRL_GRAVE = K_CTRL|0xc0|K_DELTA,
K_CTRL_SLASH = K_CTRL|0xbf|K_DELTA,
K_CTRL_BACKSLASH = K_CTRL|0xdc|K_DELTA,
K_CTRL_COMMA = K_CTRL|0xbc|K_DELTA,
K_CTRL_PERIOD = K_CTRL|0xbe|K_DELTA,
K_CTRL_SEMICOLON = K_CTRL|0xbe|K_DELTA,
K_CTRL_EQUAL = K_CTRL|0xbb|K_DELTA,
K_CTRL_APOSTROPHE= K_CTRL|0xde|K_DELTA,
K_BREAK = VK_CANCEL + K_DELTA,

126
rainbow/WinAlt/WinAltMsg.i Normal file
View file

@ -0,0 +1,126 @@
#pragma BLITZ_APPROVE
x_MSG(WM_CREATE)
x_MSG(WM_DESTROY)
x_MSG(WM_MOVE)
x_MSG(WM_SIZE)
x_MSG(WM_ACTIVATE)
x_MSG(WM_SETFOCUS)
x_MSG(WM_KILLFOCUS)
x_MSG(WM_ENABLE)
x_MSG(WM_SETREDRAW)
x_MSG(WM_SETTEXT)
x_MSG(WM_GETTEXT)
x_MSG(WM_GETTEXTLENGTH)
x_MSG(WM_PAINT)
x_MSG(WM_CLOSE)
x_MSG(WM_QUIT)
x_MSG(WM_ERASEBKGND)
x_MSG(WM_SYSCOLORCHANGE)
x_MSG(WM_SHOWWINDOW)
x_MSG(WM_WININICHANGE)
x_MSG(WM_FONTCHANGE)
x_MSG(WM_NEXTDLGCTL)
x_MSG(WM_DRAWITEM)
x_MSG(WM_MEASUREITEM)
x_MSG(WM_DELETEITEM)
x_MSG(WM_VKEYTOITEM)
x_MSG(WM_CHARTOITEM)
x_MSG(WM_SETFONT)
x_MSG(WM_GETFONT)
x_MSG(WM_QUERYDRAGICON)
x_MSG(WM_COMPAREITEM)
x_MSG(WM_GETDLGCODE)
x_MSG(WM_KEYDOWN)
x_MSG(WM_KEYUP)
x_MSG(WM_CHAR)
x_MSG(WM_DEADCHAR)
x_MSG(WM_SYSKEYDOWN)
x_MSG(WM_SYSKEYUP)
x_MSG(WM_SYSCHAR)
x_MSG(WM_SYSDEADCHAR)
x_MSG(WM_KEYLAST)
x_MSG(WM_INITDIALOG)
x_MSG(WM_COMMAND)
x_MSG(WM_SYSCOMMAND)
x_MSG(WM_TIMER)
x_MSG(WM_HSCROLL)
x_MSG(WM_VSCROLL)
x_MSG(WM_INITMENUPOPUP)
x_MSG(WM_MENUCHAR)
x_MSG(WM_LBUTTONDOWN)
x_MSG(WM_LBUTTONUP)
x_MSG(WM_LBUTTONDBLCLK)
x_MSG(WM_RBUTTONDOWN)
x_MSG(WM_RBUTTONUP)
x_MSG(WM_RBUTTONDBLCLK)
x_MSG(WM_MBUTTONDOWN)
x_MSG(WM_MBUTTONUP)
x_MSG(WM_MBUTTONDBLCLK)
x_MSG(WM_MOUSEMOVE)
x_MSG(WM_CUT)
x_MSG(WM_COPY)
x_MSG(WM_PASTE)
x_MSG(WM_CLEAR)
x_MSG(WM_UNDO)
x_MSG(WM_RENDERFORMAT)
x_MSG(WM_RENDERALLFORMATS)
x_MSG(WM_DESTROYCLIPBOARD)
x_MSG(WM_QUERYNEWPALETTE)
x_MSG(WM_PALETTECHANGED)
x_MSG(WM_WINDOWPOSCHANGED)
#ifndef PLATFORM_WINCE
x_MSG(WM_QUERYENDSESSION)
x_MSG(WM_ENDSESSION)
x_MSG(WM_QUERYOPEN)
x_MSG(WM_DEVMODECHANGE)
x_MSG(WM_ACTIVATEAPP)
x_MSG(WM_TIMECHANGE)
x_MSG(WM_MOUSEACTIVATE)
x_MSG(WM_CHILDACTIVATE)
x_MSG(WM_QUEUESYNC)
x_MSG(WM_GETMINMAXINFO)
x_MSG(WM_ICONERASEBKGND)
x_MSG(WM_SPOOLERSTATUS)
x_MSG(WM_COMPACTING)
x_MSG(WM_NCLBUTTONDOWN)
x_MSG(WM_NCLBUTTONUP)
x_MSG(WM_NCLBUTTONDBLCLK)
x_MSG(WM_NCRBUTTONDOWN)
x_MSG(WM_NCRBUTTONUP)
x_MSG(WM_NCRBUTTONDBLCLK)
x_MSG(WM_NCMBUTTONDOWN)
x_MSG(WM_NCMBUTTONUP)
x_MSG(WM_NCMBUTTONDBLCLK)
x_MSG(WM_NCCREATE)
x_MSG(WM_NCDESTROY)
x_MSG(WM_NCCALCSIZE)
x_MSG(WM_NCPAINT)
x_MSG(WM_NCACTIVATE)
x_MSG(WM_INITMENU)
x_MSG(WM_MENUSELECT)
x_MSG(WM_PARENTNOTIFY)
x_MSG(WM_MDICREATE)
x_MSG(WM_MDIDESTROY)
x_MSG(WM_MDIACTIVATE)
x_MSG(WM_MDIRESTORE)
x_MSG(WM_MDINEXT)
x_MSG(WM_MDIMAXIMIZE)
x_MSG(WM_MDITILE)
x_MSG(WM_MDICASCADE)
x_MSG(WM_MDIICONARRANGE)
x_MSG(WM_MDIGETACTIVE)
x_MSG(WM_MDISETMENU)
x_MSG(WM_DRAWCLIPBOARD)
x_MSG(WM_PAINTCLIPBOARD)
x_MSG(WM_VSCROLLCLIPBOARD)
x_MSG(WM_SIZECLIPBOARD)
x_MSG(WM_ASKCBFORMATNAME)
x_MSG(WM_CHANGECBCHAIN)
x_MSG(WM_HSCROLLCLIPBOARD)
x_MSG(WM_PALETTEISCHANGING)
x_MSG(WM_DROPFILES)
x_MSG(WM_POWER)
x_MSG(WM_WINDOWPOSCHANGING)
#endif

View file

@ -0,0 +1,502 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_WINALT
#include <winnls.h>
//#include "imm.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
dword Ctrl::KEYtoK(dword chr) {
if(chr == VK_TAB)
chr = K_TAB;
else
if(chr == VK_SPACE)
chr = K_SPACE;
else
if(chr == VK_RETURN)
chr = K_RETURN;
else
chr = chr + K_DELTA;
if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY)
return chr;
if(GetCtrl()) chr |= K_CTRL;
if(GetAlt()) chr |= K_ALT;
if(GetShift()) chr |= K_SHIFT;
return chr;
}
class NilDrawFull : public NilDraw {
virtual bool IsPaintingOp(const Rect& r) const { return true; }
};
#ifdef PLATFORM_WINCE
bool GetShift() { return false; }
bool GetCtrl() { return false; }
bool GetAlt() { return false; }
bool GetCapsLock() { return false; }
bool wince_mouseleft;
bool wince_mouseright;
bool GetMouseLeft() { return wince_mouseleft; }
bool GetMouseRight() { return wince_mouseright; }
bool GetMouseMiddle() { return false; }
Point wince_mousepos = Null;
Point GetMousePos() {
return wince_mousepos;
}
void SetWinceMouse(HWND hwnd, LPARAM lparam)
{
Point p(lparam);
ClientToScreen(hwnd, p);
wince_mousepos = p;
}
#else
void SetWinceMouse(HWND hwnd, LPARAM lparam) {}
bool GetShift() { return !!(GetKeyState(VK_SHIFT) & 0x8000); }
bool GetCtrl() { return !!(GetKeyState(VK_CONTROL) & 0x8000); }
bool GetAlt() { return !!(GetKeyState(VK_MENU) & 0x8000); }
bool GetCapsLock() { return !!(GetKeyState(VK_CAPITAL) & 1); }
bool GetMouseLeft() { return !!(GetKeyState(VK_LBUTTON) & 0x8000); }
bool GetMouseRight() { return !!(GetKeyState(VK_RBUTTON) & 0x8000); }
bool GetMouseMiddle() { return !!(GetKeyState(VK_MBUTTON) & 0x8000); }
#endif
void AvoidPaintingCheck__()
{
Ctrl::painting = false;
}
bool PassWindowsKey(int wParam);
LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
GuiLock __;
eventid++;
ASSERT_(!painting, "WindowProc invoked while in Paint routine");
// LLOG("Ctrl::WindowProc(" << message << ") in " << ::Name(this) << ", focus " << (void *)::GetFocus());
Ptr<Ctrl> _this = this;
HWND hwnd = GetHWND();
switch(message) {
case WM_PALETTECHANGED:
if((HWND)wParam == hwnd)
break;
#ifndef PLATFORM_WINCE
case WM_QUERYNEWPALETTE:
if(!SystemDraw::AutoPalette()) break;
{
HDC hDC = GetDC(hwnd);
HPALETTE hOldPal = SelectPalette(hDC, GetQlibPalette(), FALSE);
int i = RealizePalette(hDC);
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(hwnd, hDC);
LLOG("Realized " << i << " colors");
if(i) InvalidateRect(hwnd, NULL, TRUE);
return i;
}
#endif
case WM_PAINT:
ASSERT(hwnd);
if(hwnd) {
PAINTSTRUCT ps;
if(IsVisible())
SyncScroll();
HDC dc = BeginPaint(hwnd, &ps);
fullrefresh = false;
if(IsVisible()) {
SystemDraw draw(dc);
#ifndef PLATFORM_WINCE
HPALETTE hOldPal;
if(draw.PaletteMode() && SystemDraw::AutoPalette()) {
hOldPal = SelectPalette(dc, GetQlibPalette(), TRUE);
int n = RealizePalette(dc);
LLOG("In paint realized " << n << " colors");
}
#endif
painting = true;
UpdateArea(draw, Rect(ps.rcPaint));
painting = false;
#ifndef PLATFORM_WINCE
if(draw.PaletteMode() && SystemDraw::AutoPalette())
SelectPalette(dc, hOldPal, TRUE);
#endif
}
EndPaint(hwnd, &ps);
}
return 0L;
#ifndef PLATFORM_WINCE
case WM_NCHITTEST:
CheckMouseCtrl();
if(ignoremouse) return HTTRANSPARENT;
break;
#endif
case WM_LBUTTONDOWN:
#ifdef PLARFORM_WINCE
wince_mouseleft = true;
#endif
SetWinceMouse(hwnd, lParam);
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(LEFTDOWN, Point((dword)lParam), 0);
if(_this) PostInput();
return 0L;
case WM_LBUTTONUP:
if(ignoreclick)
EndIgnore();
else
DoMouse(LEFTUP, Point((dword)lParam), 0);
#ifdef PLATFORM_WINCE
wince_mouseleft = false;
#endif
#ifdef PLATFORM_WINCE
wince_mousepos = Point(-99999, -99999);
if(!ignoreclick)
if(_this) DoMouse(MOUSEMOVE, Point(-99999, -99999));
#endif
if(_this) PostInput();
return 0L;
case WM_LBUTTONDBLCLK:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(LEFTDOUBLE, Point((dword)lParam), 0);
if(_this) PostInput();
return 0L;
case WM_RBUTTONDOWN:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(RIGHTDOWN, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_RBUTTONUP:
if(ignoreclick)
EndIgnore();
else
DoMouse(RIGHTUP, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_RBUTTONDBLCLK:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(RIGHTDOUBLE, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_MBUTTONDOWN:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(MIDDLEDOWN, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_MBUTTONUP:
if(ignoreclick)
EndIgnore();
else
DoMouse(MIDDLEUP, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_MBUTTONDBLCLK:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(MIDDLEDOUBLE, Point((dword)lParam));
if(_this) PostInput();
return 0L;
#ifndef PLATFORM_WINCE
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
ClickActivateWnd();
IgnoreMouseUp();
break;
#endif
case WM_MOUSEMOVE:
SetWinceMouse(hwnd, lParam);
LLOG("WM_MOUSEMOVE: ignoreclick = " << ignoreclick);
if(ignoreclick) {
EndIgnore();
return 0L;
}
if(_this)
DoMouse(MOUSEMOVE, Point((dword)lParam));
DoCursorShape();
return 0L;
case 0x20a: // WM_MOUSEWHEEL:
if(ignoreclick) {
EndIgnore();
return 0L;
}
if(_this)
DoMouse(MOUSEWHEEL, Point((dword)lParam), (short)HIWORD(wParam));
if(_this) PostInput();
return 0L;
case WM_SETCURSOR:
if((HWND)wParam == hwnd && LOWORD((dword)lParam) == HTCLIENT) {
if(hCursor) SetCursor(hCursor);
return TRUE;
}
break;
// case WM_MENUCHAR:
// return MAKELONG(0, MNC_SELECT);
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_CHAR:
ignorekeyup = false;
case WM_KEYUP:
case WM_SYSKEYUP:
{
#if 0
String msgdump;
switch(message)
{
case WM_KEYDOWN: msgdump << "WM_KEYDOWN"; break;
case WM_KEYUP: msgdump << "WM_KEYUP"; break;
case WM_SYSKEYDOWN: msgdump << "WM_SYSKEYDOWN"; break;
case WM_SYSKEYUP: msgdump << "WM_SYSKEYUP"; break;
case WM_CHAR: msgdump << "WM_CHAR"; break;
}
msgdump << " wParam = 0x" << FormatIntHex(wParam, 8)
<< ", lParam = 0x" << FormatIntHex(lParam, 8)
<< ", ignorekeyup = " << (ignorekeyup ? "true" : "false");
LLOG(msgdump);
#endif
dword keycode = 0;
if(message == WM_KEYDOWN) {
keycode = KEYtoK((dword)wParam);
if(keycode == K_SPACE)
keycode = 0;
}
else
if(message == WM_KEYUP)
keycode = KEYtoK((dword)wParam) | K_KEYUP;
else
if(message == WM_SYSKEYDOWN /*&& ((lParam & 0x20000000) || wParam == VK_F10)*/)
keycode = KEYtoK((dword)wParam);
else
if(message == WM_SYSKEYUP /*&& ((lParam & 0x20000000) || wParam == VK_F10)*/)
keycode = KEYtoK((dword)wParam) | K_KEYUP;
else
if(message == WM_CHAR && wParam != 127 && wParam > 32 || wParam == 32 && KEYtoK(VK_SPACE) == K_SPACE) {
#ifdef PLATFORM_WINCE
keycode = wParam;
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX Unicode patch
keycode = (dword)wParam;
else {
char b[20];
::GetLocaleInfo(MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE, b, 20);
int codepage = atoi(b);
if(codepage >= 1250 && codepage <= 1258)
keycode = ToUnicode((dword)wParam, codepage - 1250 + CHARSET_WIN1250);
else
keycode = (dword)wParam;
}
#endif
}
bool b = false;
if(keycode) {
b = DispatchKey(keycode, LOWORD(lParam));
SyncCaret();
if(_this) PostInput();
}
// LOG("key processed = " << b);
if(b || (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP)
&& wParam != VK_F4 && !PassWindowsKey((dword)wParam)) // 17.11.2003 Mirek -> invoke system menu
return 0L;
break;
}
break;
// case WM_GETDLGCODE:
// return wantfocus ? 0 : DLGC_STATIC;
case WM_ERASEBKGND:
return 1L;
case WM_DESTROY:
PreDestroy();
#ifndef PLATFORM_WINCE
break;
case WM_NCDESTROY:
#endif
if(!hwnd) break;
if(HasChildDeep(mouseCtrl) || this == ~mouseCtrl) mouseCtrl = NULL;
if(HasChildDeep(focusCtrl) || this == ~focusCtrl) focusCtrl = NULL;
if(HasChildDeep(focusCtrlWnd) || this == ~focusCtrlWnd) {
LLOG("WM_NCDESTROY: clearing focusCtrlWnd = " << ::Name(focusCtrlWnd));
focusCtrlWnd = NULL;
focusCtrl = NULL;
}
if(::GetFocus() == NULL) {
Ctrl *owner = GetOwner();
if(owner && (owner->IsForeground() || IsForeground()) && !owner->SetWantFocus())
IterateFocusForward(owner, owner);
}
#ifdef PLATFORM_WINCE
DefWindowProc(hwnd, message, wParam, lParam);
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX unicode patch
DefWindowProcW(hwnd, message, wParam, lParam);
else
DefWindowProc(hwnd, message, wParam, lParam);
#endif
hwnd = NULL;
return 0L;
case WM_CANCELMODE:
if(this == ~captureCtrl || HasChildDeep(captureCtrl))
ReleaseCtrlCapture();
break;
case WM_SHOWWINDOW:
visible = (BOOL) wParam;
StateH(SHOW);
break;
#ifndef PLATFORM_WINCE
case WM_MOUSEACTIVATE:
LLOG("WM_MOUSEACTIVATE " << Name() << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
if(!IsEnabled()) {
if(lastActiveWnd && lastActiveWnd->IsEnabled()) {
LLOG("WM_MOUSEACTIVATE -> ::SetFocus for " << UPP::Name(lastActiveWnd));
::SetFocus(lastActiveWnd->GetHWND());
}
else
MessageBeep(MB_OK);
return MA_NOACTIVATEANDEAT;
}
if(IsPopUp()) return MA_NOACTIVATE;
break;
#endif
case WM_SIZE:
case WM_MOVE:
if(hwnd) {
Rect rect;
#ifndef PLATFORM_WINCE
if(activex) {
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWINFO);
::GetWindowPlacement(hwnd, &wp);
rect = wp.rcNormalPosition;
}
else
#endif
rect = GetScreenClient(hwnd);
LLOG("WM_MOVE / WM_SIZE: screen client = " << rect);
if(GetRect() != rect)
SetWndRect(rect);
WndDestroyCaret();
caretCtrl = NULL;
SyncCaret();
}
return 0L;
case WM_HELP:
return TRUE;
case WM_ACTIVATE:
LLOG("WM_ACTIVATE " << Name() << ", wParam = " << (int)wParam << ", focusCtrlWnd = " << ::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
ignorekeyup = true;
break;
case WM_SETFOCUS:
LLOG("WM_SETFOCUS " << Name() << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
if(this != focusCtrlWnd)
if(IsEnabled()) {
LLOG("WM_SETFOCUS -> ActivateWnd: this != focusCtrlWnd, this = "
<< Name() << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd));
ActivateWnd();
}
else {
if(focusCtrlWnd && focusCtrlWnd->IsEnabled()) {
if(!IsEnabled())
MessageBeep(MB_OK);
LLOG("WM_SETFOCUS -> ::SetFocus for " << UPP::Name(focusCtrlWnd));
::SetFocus(focusCtrlWnd->GetHWND());
}
else
if(lastActiveWnd && lastActiveWnd->IsEnabled()) {
LLOG("WM_SETFOCUS -> ::SetFocus for " << UPP::Name(lastActiveWnd));
::SetFocus(lastActiveWnd->GetHWND());
}
else {
LLOG("WM_SETFOCUS - ::SetFocus(NULL)");
::SetFocus(NULL);
}
}
LLOG("//WM_SETFOCUS " << (void *)hwnd << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
return 0L;
case WM_KILLFOCUS:
LLOG("WM_KILLFOCUS " << (void *)(HWND)wParam << ", this = " << UPP::Name(this) << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
LLOG("Kill " << ::Name(CtrlFromHWND((HWND)wParam)));
if(!CtrlFromHWND((HWND)wParam)) {
LLOG("WM_KILLFOCUS -> KillFocusWnd: " << UPP::Name(this));
KillFocusWnd();
}
LLOG("//WM_KILLFOCUS " << (void *)(HWND)wParam << ", focusCtrlWnd = " << ::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
return 0L;
case WM_ENABLE:
if(!!wParam != enabled) {
enabled = !!wParam;
RefreshFrame();
StateH(ENABLE);
}
return 0L;
#ifndef PLATFORM_WINCE
case WM_GETMINMAXINFO:
{
MINMAXINFO *mmi = (MINMAXINFO *)lParam;
Rect frmrc = Size(200, 200);
::AdjustWindowRect(frmrc, WS_OVERLAPPEDWINDOW, FALSE);
Size msz = Ctrl::GetWorkArea().Deflated(-frmrc.left, -frmrc.top,
frmrc.right - 200, frmrc.bottom - 200).GetSize();
Rect minr(Point(50, 50), min(msz, GetMinSize()));
Rect maxr(Point(50, 50), min(msz, GetMaxSize()));
dword style = ::GetWindowLong(hwnd, GWL_STYLE);
dword exstyle = ::GetWindowLong(hwnd, GWL_EXSTYLE);
AdjustWindowRectEx(minr, style, FALSE, exstyle);
AdjustWindowRectEx(maxr, style, FALSE, exstyle);
mmi->ptMinTrackSize = Point(minr.Size());
mmi->ptMaxTrackSize = Point(maxr.Size());
LLOG("WM_GETMINMAXINFO: MinTrackSize = " << Point(mmi->ptMinTrackSize) << ", MaxTrackSize = " << Point(mmi->ptMaxTrackSize));
LLOG("ptMaxSize = " << Point(mmi->ptMaxSize) << ", ptMaxPosition = " << Point(mmi->ptMaxPosition));
}
return 0L;
#endif
case WM_SETTINGCHANGE:
case 0x031A: // WM_THEMECHANGED
ChSync();
RefreshLayoutDeep();
RefreshFrame();
break;
/*
case WM_IME_COMPOSITION:
HIMC himc = ImmGetContext(hwnd);
if(!himc) break;
CANDIDATEFORM cf;
Rect r = GetScreenRect();
cf.dwIndex = 0;
cf.dwStyle = CFS_CANDIDATEPOS;
cf.ptCurrentPos.x = r.left + caretx;
cf.ptCurrentPos.y = r.top + carety + caretcy;
ImmSetCandidateWindow (himc, &cf);
break;
*/
}
if(hwnd)
#ifdef PLATFORM_WINCE
return DefWindowProc(hwnd, message, wParam, lParam);
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX unicode patch
return DefWindowProcW(hwnd, message, wParam, lParam);
else
return DefWindowProc(hwnd, message, wParam, lParam);
#endif
return 0L;
}
void Ctrl::PreDestroy() {}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,20 @@
//$ class TopWindow {
public:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
private:
dword style;
dword exstyle;
HICON ico, lico;
void DeleteIco0();
void DeleteIco();
void CenterRect(HWND owner, int center);
public:
void Open(HWND ownerhwnd);
TopWindow& Style(dword _style);
dword GetStyle() const { return style; }
TopWindow& ExStyle(dword _exstyle);
dword GetExStyle() const { return exstyle; }
//$ };

1338
rainbow/WinAlt/WinAltWnd.cpp Normal file

File diff suppressed because it is too large Load diff

3
rainbow/WinAlt/init Normal file
View file

@ -0,0 +1,3 @@
#ifndef _WinAlt_icpp_init_stub
#define _WinAlt_icpp_init_stub
#endif

2
rainbow/guiplatform.h Normal file
View file

@ -0,0 +1,2 @@
#define GUIPLATFORM_INCLUDE <WinAlt/WinAlt.h>