Skip to content

48 featapp características a nivel de app lifecycle systemtray culture system dialogs alternativewindow - #57

Merged
cl2raul66 merged 24 commits into
developfrom
48-featapp-características-a-nivel-de-app-lifecycle-systemtray-culture-system-dialogs-alternativewindow
Oct 11, 2026

Hidden character warning

The head ref may contain hidden characters: "48-featapp-caracter\u00edsticas-a-nivel-de-app-lifecycle-systemtray-culture-system-dialogs-alternativewindow"
Merged

cl2raul66 merged 24 commits into
developfrom
48-featapp-características-a-nivel-de-app-lifecycle-systemtray-culture-system-dialogs-alternativewindow

Conversation

@cl2raul66

Copy link
Copy Markdown
Owner

Versioning

ver(core): 1.4.3-preview
ver(gen): 1.1.2-preview
ver(template): 1.2.2-preview

Fase 0: IViewSurface como contrato común (View<T>/IControl/ViewModel relajados), IMenu/IMenuItem. Fase 1: motor HMENU Win32 puro (Win32MenuEngine + MenuSurface + MenuItem). Fase 2: SystemTray (broker + triggers tipados sin nombres de dispositivo, LongTap/Holding derivados), AlternativeWindow<T>, rama IMenu, .SystemTray() en IWindowConfig. Fase 3: generator (GetSurface<T>), bh.SystemTray, fusión IAppBehavior (TaskbarButtonVisibility, OnLaunched real). Fase 4: docs (system_design + propuestas) y Sample compilable. Extra: IMenuItemSeparator + overload View<T>() anónimo. Breaking: eliminados ISystemTrayConfig/ISystemTrayMenuBuilder, ShowInTaskbar/SetupSystemTray/RemoveSystemTray.
…48)

Broker: máscara LOWORD + guard HIWORD (VERSION_4 empaqueta lParam), WM_CONTEXTMENU por callback con heurística de cursor, TaskbarList por vtable (adiós NotSupportedException de ComImport), higiene (callback!=0, AddIcon con throw). Tooltip clásico vía NIF_SHOWTIP; grupo ISystemTrayNotifications (IToolTipService + ITrayNotificationService); TooltipShow/Hide pasan a Notify/DismissNotification. MenuSurface se ancla al icono (fix HRESULT invertido). Culture automático (OS) + catálogo Cultures generado con global using static; Sample con preset pelado y OnClick en items.
…yText/SecondaryText, NotificationIcon, Choices/DefaultChoice, TaskDialogChoice enum
…lect/DefaultFileName/DefaultExtension to Content(builder); add PersistLastDirectory to SelectFolderDialog
…puted from FilePattern, eliminates magic strings
…s, STA pipeline, naming rationale, DefaultExtension(FilePattern)
…, FileDialogNative, DialogSurfaceBase, FileDialogFiltersBuilder, ISystemDialog
…nativeWindow (#48)

Superficie: IAppBehavior.Terminate(); Close/Closing/Closed solo en IAlternativeWindow. Wiring: MasterRouter.TerminationGate (X y Terminate pasan por OnTerminating vetable), OnTerminated tras el loop. Secundarias: Close destruye con veto local, Show re-crea a demanda. Sample con ConfirmExit + Terminate; docs en system_design.
…aries (#48)

(1) EnsureCreated reutiliza instancias (sobreviven suscripciones y estado); Children.Clear() en UserControl reutilizados. (2) DeleteObject del brush de ventana en WM_DESTROY. (3) Centrado con _positionMode vivo. (5) Destroy de secundarias vivas pre-OnTerminated via LiveWindows(). Docs Lifecycle en system_design.
…t spec (ITapCountSpec) - #49

- ITapCountSpec base interface unificando ITapCount + NoTap + AnyTap
- SurfaceInputHub: _spatial unificado (Trigger, CountSpec); Fire despacha AnyTap/Specific/NoTap
- 5 implementaciones: OnInputWithSpatialPosition<TTrigger> -> AnyTap; () -> MainTap+OneTap
- Sample modernizado al nuevo dialecto
- SurfaceInputExtensions removidas (redundantes)

Resolves #49.
…r WM_DESTROY split - prep #51/#52

- HandleRegistry.UnregisterWindowHwndOnly: remueve hwnd, conserva name para re-creacion
- MasterRouter: AlternativeWindowImpl usa HwndOnly; main window borra ambas
- CONTRIBUTING: documenta regla hwnd-only
- system_design: aclara lifecycle secundarias
- README/.gitignore: updates menores

Prep #51 (router dict cleanup) / #52 (HandleRegistry entity table).
…54

- Share/IBaseWindow.cs: OnLoaded, OnActivated, OnDeactivated
- Share/IAlternativeWindow.cs: OnClosing(CancelEventArgs), OnClosed
- Share/IWindow.cs: OnResizing, OnResized, OnMoved
- Core/Windowing/WindowImpl.cs: 6 OnX methods delegating to events
- Core/Windowing/AlternativeWindowImpl.cs: 5 OnX methods delegating to events
- Core/ControlBase.cs: remove Closing/Closed stubs; no-op OnLoaded/OnActivated/OnDeactivated
- Sample/Program.cs: migrate to OnLoaded/OnClosing/OnClosed dialect
- CONTRIBUTING.md: document Behavior-first dialect rule

Events remain as internal mechanism; OnX is typed sugar aligning with IAppBehavior.
Resolves #54. Prerequisite for documenting #48.
…finement #54)

- Core/Windowing/WindowImpl.cs: validate handler != null in all 6 OnX methods
- Core/Windowing/AlternativeWindowImpl.cs: validate handler != null in all 5 OnX methods

Ensures fail-fast semantics per refinement: multiple subscriptions allowed, no Off in v1.
- CONTRIBUTING.md: fix ❌ examples to use real legacy events (OtherWindow.Loaded/Closing/Closed)
- Sample/Program.cs: remove 15 lines of dead commented code (lines 133-147)
- WindowImpl/AlternativeWindowImpl: revert ArgumentNullException guards (Option A) for consistency with IAppBehavior/IInputSurface/ControlBase

Resolves #54.
- Core/MasterRouter.cs: CleanupHwnd(nint) exhaustive cleanup of 5 dicts + Debug.Assert
- Core/MasterRouter.cs: WM_DESTROY uses CleanupHwnd (removes duplicated cleanup code)
- Core/Windowing/AlternativeWindowImpl.cs: EnsureCreated() defensive CleanupHwnd before RegisterRouter

Prevents stale state on Close()/Show() cycles and theoretical hwnd-reuse.
Prepares semantics for #52 (HandleRegistry entity table) to absorb in cascade.
Resolves #51.
…1+B-2) — #52

- Core/HandleRegistry.cs: EntityEntry (Id, Kind, Hwnd, Name, Strong/Weak, ChildrenIds) + motor Attach/DetachHandle/Remove/DetachWindowByHwnd
- Core/HandleRegistry.cs: legacy facade eliminado (Unregister*/TrackChildWindow/ClearAllControls); se conserva RegisterWindow como upsert por nombre (re-creación de secundarias conserva Id)
- Core/HandleRegistry.cs: GetByHwnd/GetByName/GetWindow/GetSurface sobre _entries + índices derivados (_byHwnd, _byName)
- Core/HandleRegistry.cs: RemoveAll() para teardown total + Debug.Assert vacía
- Core/MasterRouter.cs: WM_DESTROY usa DetachWindowByHwnd(policy) (1 llamada; policy explícita Remove/DetachHandle) + CleanupHwnd (#51); DebugAssertHwndUnregistered post UnregisterRouter (B-2, DEBUG)
- Core/Application.cs: RegisterMain/RegisterAlternative/RegisterAlternativeDialog/SetupSystemTrayIcon usan Attach; epílogo post-loop llama RemoveAll
- Win32ControlsModule/Backend/Win32NativeHandleFactory.cs: CreateHandle con Attach(Control, ..., parentHwnd) en 1 llamada (antes Register + TrackChildWindow)
- Core/Menus/MenuSurface.cs: RegisterSurface → Attach(Surface, hwnd:0)
- CONTRIBUTING.md: bulletes Core + HandleRegistry actualizados a entity store (índices derivados, verbos Attach/DetachHandle/Remove, grafo ChildrenIds, routers estáticos aparte)

Elimina gestión manual de índices; codifica semántica #50 (Detach vs Remove) por construcción. Habilita #47 sobre lifecycle sano. Resolves #52.
- AlternativeWindowImpl: _tearingDown flag + MarkTearingDown(), guards en RaiseClosing/RaiseClosed
- Application: epílogo post-message-loop marca tearingDown antes de DestroyWindow en secundarias vivas
- IAlternativeWindow: doc XML OnClosed no corre en teardown (usar IAppBehavior.OnTerminated)
- CONTRIBUTING.md: dialecto Behavior-first — teardown no dispara Closing/Closed
- system_design.md: sección Teardown corregida (sin callbacks de Behavior)

El teardown ya omitía Closing; ahora también omite Closed. Fix del NRE cuando
la secundaria estaba viva (aún oculta) al cerrar la principal.
Resolves #55. Continúa la semántica iniciada en #48, desbloquea #47.
Share (Phase A/B):
- New types: WindowState, TitleBarMode+ITitleBarConfig, CaptionButtons, WindowBackdrop, ScreenCaptureMode, WindowPosition (+PositionAt/PositionPreset/PositionSnap + presets)
- IWindowConfig: MinSize/MaxSize/Position(IWindowPosition)/Resizable/CaptionButtons/TopMost/Opacity/SystemBackdrop/ScreenCapture/WindowState/TitleBar; Position(WindowPositionOnScreen) -> [Obsolete]
- IWindow: State, EnterFullScreen/ExitFullScreen, TopMost, Opacity, Backdrop, ScreenCapture, MinSize/MaxSize, Resizable, CaptionButtons, BringToFront/SendToBack

Core (Phase B):
- WindowModel extendido (TitleBar, MinSize, MaxSize, Resizable, CaptionButtons, TopMost, Opacity, Backdrop, ScreenCapture, InitialWindowState, WindowPosition)
- WindowConfigBuilder: fluent de todas las nuevas (incluye TitleBarConfigBuilder)
- Application: ApplyModelProps/ApplyWindowPosition (preset/snap) wiring tras Attach

WindowImpl (Phase C):
- State (sync IsZoomed/IsIconic), FullScreen nativo (guarda/restore GWL_STYLE+EXSTYLE+RECT), TopMost, Opacity (WS_EX_LAYERED + SetLayeredWindowAttributes), Backdrop (DwmSetWindowAttribute SYSTEMBACKDROP_TYPE, feature-detect Win10 1809+), ScreenCapture (SetWindowDisplayAffinity con fallback), MinSize/MaxSize, Resizable (WS_THICKFRAME), CaptionButtons (SYSMENU/MINIMIZE/MAXIMIZE), BringToFront/SendToBack
- ApplyMinMaxInfo (MINMAXINFO: min/max track + MaximizedBounds del monitor), SyncStateFromSysCommand

MasterRouter (Phase D):
- WM_GETMINMAXINFO (unsafe pointer a MINMAXINFO, delega a WindowImpl)
- WM_SYSCOMMAND (sync State desde SC_MINIMIZE/MAXIMIZE/RESTORE)

Win32/Constants: + SetLayeredWindowAttributes, SetWindowDisplayAffinity, IsZoomed/IsIconic, DwmSetWindowAttribute, DwmExtendFrameIntoClientArea, IsWindows10_1809OrLater; clases SC/DWMWA/DWMSBT/HT/WDA/LWA; WS_EX.LAYERED/RTLREADING; WM 0x24/0x83/0x84/0x86; structs MARGINS/MINMAXINFO/CWPSTRUCT; M  Sincronización SW/SWP/GWL preexistentes; RECT movido (Core/RECT.cs borrado, consolidado en Entities.cs)

Sample: actualizado
…eyMenu trigger

- Core/Constants.cs: SC.KEYMENU = 0xF100 constant
- Core/Win32.cs: ResolveFullScreenBounds() taskbar-aware (SHAppBarMessage + ABS_AUTOHIDE)
- Core/Windowing/WindowImpl.cs: EnterFullScreen/ExitFullScreen (rcWork/rcMonitor), State sync, Opacity, TopMost, Backdrop, ScreenCapture, FullScreen, MinSize/MaxSize, CaptionButtons, Resizable, Z-order
- Core/MasterRouter.cs: WM_SYSCOMMAND handles SC_KEYMENU → KeyMenu trigger, WM_GETMINMAXINFO delegates to ApplyMinMaxInfo
- Core/Entities.cs: RECT/POINT back to int (Win32 ABI compliance)
- Core/Application.cs: Position presets/snaps with int casts
- Share/: WindowState, WindowBackdrop, WindowPosition (discriminated), TitleBarMode/ITitleBarConfig, CaptionButtons, ScreenCaptureMode, IWindow/IWindowConfig extensions
- Sample: Updated to use new APIs (FullScreen, State, MaxSize, Z-order, KeyMenu trigger)

Phase C ~90% complete (falta TitleBar.Custom hit-test), Phase D pending (MasterRouter routing for custom title bar).
Resolves #56 (taskbar-aware FullScreen + KeyMenu trigger).
#47

- Core/Windowing/WindowImpl.cs: added _titleBarMode field + TitleBarActive property (covers Custom + Simple)
- Core/MasterRouter.cs: WM_NCACTIVATE now checks TitleBarActive (Custom + Simple)
- Core/Windowing/WindowImpl.cs: ApplyTitleBar stores TitleBarMode

Completes Phase D of #47: Custom title bar fully functional (drag, activate, frame).
@cl2raul66
cl2raul66 merged commit c26af87 into develop Oct 11, 2026
@cl2raul66
cl2raul66 deleted the 48-featapp-características-a-nivel-de-app-lifecycle-systemtray-culture-system-dialogs-alternativewindow branch October 11, 2026 19:03

This branch was successfully deployed

1 active deployment
dev — 203882dd Deployed Oct 11, 2026 by cl2raul66 via publish-preview #14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant