bool GWindow::SetPos(GRect &p, bool Repaint) { if (Wnd) { if (p.x1 < -100) { printf("%s:%i - Weird setpos(%s)\n", __FILE__, __LINE__, p.GetStr()); } bool Lock = Wnd->Lock(); Wnd->MoveTo(p.x1, p.y1); Wnd->ResizeTo(p.X(), p.Y()); if (!Handle()->Parent()) { // Our view is not attached yet, so move it ourself BRect r = Wnd->Bounds(); Handle()->MoveTo(0, 0); Handle()->ResizeTo(r.Width(), r.Height()); } if (Lock) Wnd->Unlock(); Pos = p; return true; } return false; }
GMessage::Result GWindow::OnEvent(GMessage *Msg) { int Status = 0; switch (MsgCode(Msg)) { case M_SET_WINDOW_PLACEMENT: { /* Apparently if you use SetWindowPlacement inside the WM_CREATE handler, then the restored rect doesn't "stick", it gets stomped on by windows. So this code... RESETS it to be what we set earlier. Windows sucks. */ if (d->Wp) { if (_View) { GRect r = d->Wp->rcNormalPosition; if (!GView::Visible()) { d->Wp->showCmd = SW_HIDE; } #if DEBUG_WINDOW_PLACEMENT LgiTrace("%s:%i - SetWindowPlacement, pos=%s, show=%i\n", __FILE__, __LINE__, r.GetStr(), d->Wp->showCmd); #endif SetWindowPlacement(_View, d->Wp); } DeleteObj(d->Wp); } break; } case WM_SYSCOLORCHANGE: { LgiInitColours(); break; } case WM_WINDOWPOSCHANGING: { bool Icon = IsIconic(Handle()); bool Zoom = IsZoomed(Handle()); if (!Icon && (_Dialog || !Zoom)) { WINDOWPOS *Info = (LPWINDOWPOS) Msg->b; if (!Info) break; if (Info->flags == (SWP_NOSIZE | SWP_NOMOVE) && _Dialog) { // Info->flags |= SWP_NOZORDER; Info->hwndInsertAfter = _Dialog->Handle(); } if (GetMinimumSize().x && GetMinimumSize().x > Info->cx) { Info->cx = GetMinimumSize().x; } if (GetMinimumSize().y && GetMinimumSize().y > Info->cy) { Info->cy = GetMinimumSize().y; } RECT Rc; if (d->SnapToEdge && SystemParametersInfo(SPI_GETWORKAREA, 0, &Rc, SPIF_SENDCHANGE)) { GRect r = Rc; GRect p(Info->x, Info->y, Info->x + Info->cx - 1, Info->y + Info->cy - 1); if (r.Valid() && p.Valid()) { int Snap = 12; if (abs(p.x1 - r.x1) <= Snap) { // Snap left edge Info->x = r.x1; } else if (abs(p.x2 - r.x2) <= Snap) { // Snap right edge Info->x = r.x2 - Info->cx + 1; } if (abs(p.y1 - r.y1) <= Snap) { // Snap top edge Info->y = r.y1; } else if (abs(p.y2 - r.y2) <= Snap) { // Snap bottom edge Info->y = r.y2 - Info->cy + 1; } } } } break; } case WM_SIZE: { if (Visible()) { GWindowZoom z = d->Show; switch (Msg->a) { case SIZE_MINIMIZED: { z = GZoomMin; break; } case SIZE_MAXIMIZED: { z = GZoomMax; break; } case SIZE_RESTORED: { z = GZoomNormal; break; } } if (z != d->Show) { OnZoom(d->Show = z); } } Status = GView::OnEvent(Msg); break; } case WM_ACTIVATE: { // This is a hack to make Windows set the focus of a child // control when you Alt-Tab in and out of a top level window if (LOWORD(Msg->a) != WA_INACTIVE) { /* // gaining focus if (LastFocus) { if (In_SetWindowPos) { assert(0); LgiTrace("%s:%i - %s->SetFocus()\n", __FILE__, __LINE__, GetClass()); } SetFocus(LastFocus); LastFocus = 0; } if (d->Focus && d->Focus->Handle()) { if (In_SetWindowPos) { assert(0); LgiTrace("%s:%i - %s->SetFocus()\n", __FILE__, __LINE__, GetClass()); } else { ::SetFocus(d->Focus->Handle()); } } */ } /* else { // losing focus LastFocus = 0; HWND f = GetFocus(); for (HWND p = ::GetParent(f); p; p = ::GetParent(p)) { if (p == Handle()) { LastFocus = f; } } } */ break; } case WM_CREATE: { Pour(); OnCreate(); if (!_Default) { _Default = FindControl(IDOK); if (_Default) { _Default->Invalidate(); } } d->InCreate = false; if (d->Wp) { PostEvent(M_SET_WINDOW_PLACEMENT); } break; } case WM_WINDOWPOSCHANGED: { DeleteObj(d->Wp); Status = GView::OnEvent(Msg); break; } case WM_QUERYENDSESSION: case WM_CLOSE: { bool QuitApp; if (QuitApp = OnRequestClose(MsgCode(Msg) == WM_QUERYENDSESSION)) { Quit(); } if (MsgCode(Msg) == WM_CLOSE) { return 0; } else { return QuitApp; } break; } case WM_SYSCOMMAND: { if (Msg->a == SC_CLOSE) { if (OnRequestClose(false)) { Quit(); } return 0; } else { Status = GView::OnEvent(Msg); } break; } case WM_DROPFILES: { HDROP hDrop = (HDROP) Msg->a; if (hDrop) { GArray<char*> FileNames; int Count = 0; Count = DragQueryFileW(hDrop, -1, NULL, 0); for (int i=0; i<Count; i++) { char16 FileName[256]; if (DragQueryFileW(hDrop, i, FileName, sizeof(FileName)-1) > 0) { FileNames.Add(LgiNewUtf16To8(FileName)); } } OnReceiveFiles(FileNames); FileNames.DeleteArrays(); } break; } case M_HANDLEMOUSEMOVE: { // This receives events fired from the GMouseHookPrivate class so that // non-LGI windows create mouse hook events as well. GTempView v((OsView)MsgB(Msg)); GMouse m; m.x = LOWORD(MsgA(Msg)); m.y = HIWORD(MsgA(Msg)); HandleViewMouse(&v, m); break; } case M_COMMAND: { HWND OurWnd = Handle(); // copy onto the stack, because // we might lose the 'this' object in the // OnCommand handler which would delete // the memory containing the handle. Status = OnCommand(Msg->a, 0, (HWND) Msg->b); if (!IsWindow(OurWnd)) { // The window was deleted so break out now break; } // otherwise fall thru to the GView handler } default: { Status = GView::OnEvent(Msg); break; } } return Status; }
bool GWindow::SerializeState(GDom *Store, const char *FieldName, bool Load) { if (!Store || !FieldName) return false; #if DEBUG_SERIALIZE_STATE LgiTrace("GWindow::SerializeState(%p, %s, %i)\n", Store, FieldName, Load); #endif if (Load) { GVariant v; if (Store->GetValue(FieldName, v) && v.Str()) { GRect Position(0, 0, -1, -1); GWindowZoom State = GZoomNormal; #if DEBUG_SERIALIZE_STATE LgiTrace("\t::SerializeState:%i v=%s\n", __LINE__, v.Str()); #endif GToken t(v.Str(), ";"); for (int i=0; i<t.Length(); i++) { char *Var = t[i]; char *Value = strchr(Var, '='); if (Value) { *Value++ = 0; if (stricmp(Var, "State") == 0) State = (GWindowZoom)atoi(Value); else if (stricmp(Var, "Pos") == 0) { GRect r; r.SetStr(Value); if (r.Valid()) Position = r; } } else return false; } #if DEBUG_SERIALIZE_STATE LgiTrace("\t::SerializeState:%i State=%i, Pos=%s\n", __LINE__, State, Position.GetStr()); #endif // Apply any shortcut override int Show = LgiApp->GetShow(); if (Show == SW_SHOWMINIMIZED || Show == SW_SHOWMINNOACTIVE || Show == SW_MINIMIZE) { State = GZoomMin; } else if (Show == SW_SHOWMAXIMIZED || Show == SW_MAXIMIZE) { State = GZoomMax; } WINDOWPLACEMENT *Wp = new WINDOWPLACEMENT; if (Wp) { ZeroObj(*Wp); Wp->length = sizeof(*Wp); if (Visible()) { if (State == GZoomMax) { Wp->showCmd = SW_SHOWMAXIMIZED; } else if (State == GZoomMin) { Wp->showCmd = SW_MINIMIZE; } else { Wp->showCmd = SW_NORMAL; } } else { Wp->showCmd = SW_HIDE; d->Show = State; } if (Position.Valid() && Position.x1 >= 0 && Position.y1 >= 0) Pos = Position; else Pos.ZOff(800, 600); Wp->rcNormalPosition = Pos; #if DEBUG_SERIALIZE_STATE LgiTrace("%s:%i - SetWindowPlacement, pos=%s, show=%i\n", __FILE__, __LINE__, Pos.GetStr(), Wp->showCmd); #endif SetWindowPlacement(Handle(), Wp); if (d->InCreate) { DeleteObj(d->Wp); d->Wp = Wp; } else { DeleteObj(Wp); } } } else return false; } else { char s[256]; GWindowZoom State = GetZoom(); GRect Position; if (Handle()) { WINDOWPLACEMENT Wp; ZeroObj(Wp); Wp.length = sizeof(Wp); GetWindowPlacement(Handle(), &Wp); Position = Wp.rcNormalPosition; } else { // A reasonable fall back if we don't have a window... Position = GetPos(); } sprintf_s(s, sizeof(s), "State=%i;Pos=%s", State, Position.GetStr()); #if DEBUG_SERIALIZE_STATE LgiTrace("\t::SerializeState:%i s='%s'\n", __LINE__, s); #endif GVariant v = s; if (!Store->SetValue(FieldName, v)) return false; } return true; }
bool GView::_Mouse(GMouse &m, bool Move) { ThreadCheck(); #if 0 if (!Move) { m.Trace("_Mouse"); ::GArray<GViewI*> _m; for (GViewI *i=this; i; i=i->GetParent()) { _m.Add(i); } for (int n=0; n<_m.Length(); n++) { GViewI *i=_m[_m.Length()-1-n]; char s[256]; ZeroObj(s); memset(s, ' ', (n+1)*2); LgiTrace("%s%s %s\n", s, i->GetClass(), i->GetPos().GetStr()); } } #endif #if DEBUG_MOUSE_EVENTS LgiTrace("%s:%i - _Mouse([%i,%i], %i)\n", _FL, m.x, m.y, Move); #endif if ( !_View || ( GetWindow() && !GetWindow()->HandleViewMouse(this, m) ) ) { #if DEBUG_MOUSE_EVENTS LgiTrace("%s:%i - HandleViewMouse consumed event, _View=%p\n", _FL, _View); #endif return false; } GViewI *cap = _Capturing; #if DEBUG_MOUSE_EVENTS LgiTrace("%s:%i - _Capturing=%p/%s\n", _FL, _Capturing, _Capturing ? _Capturing->GetClass() : NULL); #endif if (_Capturing) { if (Move) { GMouse Local = lgi_adjust_click(m, _Capturing); LgiToGtkCursor(_Capturing, _Capturing->GetCursor(Local.x, Local.y)); #if DEBUG_MOUSE_EVENTS LgiTrace("%s:%i - Local=%i,%i\n", _FL, Local.x, Local.y); #endif _Capturing->OnMouseMove(Local); // This can set _Capturing to NULL } else { _Capturing->OnMouseClick(lgi_adjust_click(m, _Capturing)); } } else { if (Move) { bool Change = false; GViewI *o = WindowFromPoint(m.x, m.y); if (_Over != o) { #if DEBUG_MOUSE_EVENTS LgiTrace("%s:%i - _Over changing from %p/%s to %p/%s\n", _FL, _Over, _Over ? _Over->GetClass() : NULL, o, o ? o->GetClass() : NULL); #endif if (_Over) _Over->OnMouseExit(lgi_adjust_click(m, _Over)); _Over = o; if (_Over) _Over->OnMouseEnter(lgi_adjust_click(m, _Over)); } } GView *Target = dynamic_cast<GView*>(_Over ? _Over : this); GRect Client = Target->GView::GetClient(false); m = lgi_adjust_click(m, Target, !Move); if (!Client.Valid() || Client.Overlap(m.x, m.y)) { LgiToGtkCursor(Target, Target->GetCursor(m.x, m.y)); if (Move) { Target->OnMouseMove(m); } else { #if 0 if (!Move) { char Msg[256]; sprintf(Msg, "_Mouse Target %s", Target->GetClass()); m.Trace(Msg); } #endif Target->OnMouseClick(m); } } else if (!Move) { #if DEBUG_MOUSE_EVENTS LgiTrace("%s:%i - Click outside %s %s %i,%i\n", _FL, Target->GetClass(), Client.GetStr(), m.x, m.y); #endif } } return true; }