@@ -6,16 +6,21 @@ use std::{
66
77use compio:: driver:: syscall;
88use inherit_methods_macro:: inherit_methods;
9+ use windows:: core:: HRESULT ;
910use windows_sys:: {
10- Win32 :: UI :: {
11- Controls :: {
12- TCIF_TEXT , TCITEMW , TCM_ADJUSTRECT , TCM_DELETEALLITEMS , TCM_DELETEITEM , TCM_GETCURSEL ,
13- TCM_GETITEMCOUNT , TCM_INSERTITEMW , TCM_SETCURSEL , TCM_SETITEMW , TCN_SELCHANGE ,
14- TCS_TABS , WC_TABCONTROLW ,
15- } ,
16- WindowsAndMessaging :: {
17- GetClientRect , GetParent , MoveWindow , SW_HIDE , SW_SHOW , SendMessageW , ShowWindow ,
18- WM_NOTIFY , WS_CHILD , WS_CLIPCHILDREN , WS_EX_CONTROLPARENT , WS_TABSTOP , WS_VISIBLE ,
11+ Win32 :: {
12+ Foundation :: ERROR_ALREADY_EXISTS ,
13+ UI :: {
14+ Controls :: {
15+ TCIF_TEXT , TCITEMW , TCM_ADJUSTRECT , TCM_DELETEALLITEMS , TCM_DELETEITEM ,
16+ TCM_GETCURSEL , TCM_GETITEMCOUNT , TCM_INSERTITEMW , TCM_SETCURSEL , TCM_SETITEMW ,
17+ TCN_SELCHANGE , TCS_TABS , WC_TABCONTROLW ,
18+ } ,
19+ WindowsAndMessaging :: {
20+ GetClientRect , GetParent , HWND_MESSAGE , MoveWindow , SW_HIDE , SW_SHOW , SendMessageW ,
21+ SetParent , ShowWindow , WM_NOTIFY , WS_CHILD , WS_CLIPCHILDREN , WS_EX_CONTROLPARENT ,
22+ WS_TABSTOP , WS_VISIBLE ,
23+ } ,
1924 } ,
2025 } ,
2126 w,
@@ -24,7 +29,7 @@ use winio_handle::{AsContainer, AsWidget, BorrowedContainer};
2429use winio_primitive:: { Point , Size } ;
2530use winio_ui_windows_common:: children_refresh_dark_mode;
2631
27- use crate :: { Result , View , Widget , WindowMessageNotify , ui:: with_u16c} ;
32+ use crate :: { Error , Result , View , Widget , WindowMessageNotify , ui:: with_u16c} ;
2833
2934#[ derive( Debug ) ]
3035pub struct TabView {
@@ -164,6 +169,21 @@ impl TabView {
164169 }
165170
166171 pub fn insert ( & mut self , i : usize , item : & TabViewItem ) -> Result < ( ) > {
172+ if item. inner . borrow ( ) . index . is_some ( ) {
173+ return Err ( Error :: from_hresult ( HRESULT :: from_win32 (
174+ ERROR_ALREADY_EXISTS ,
175+ ) ) ) ;
176+ }
177+ let item_hwnd = item. as_container ( ) . as_win32 ( ) ;
178+ let previous_parent = unsafe { GetParent ( item_hwnd) } ;
179+ let new_parent = self . as_widget ( ) . as_win32 ( ) ;
180+ if previous_parent == new_parent {
181+ return Err ( Error :: from_hresult ( HRESULT :: from_win32 (
182+ ERROR_ALREADY_EXISTS ,
183+ ) ) ) ;
184+ }
185+ unsafe { SetParent ( item_hwnd, new_parent) } ;
186+
167187 self . views . insert ( i, item. clone ( ) ) ;
168188 {
169189 let mut inner = item. inner . borrow_mut ( ) ;
@@ -194,7 +214,10 @@ impl TabView {
194214 let cur = self . selection ( ) ?;
195215 let need_reselect = cur == Some ( i) ;
196216 self . handle . send_message ( TCM_DELETEITEM , i, 0 ) ;
197- self . views . remove ( i) ;
217+ let item = self . views . remove ( i) ;
218+ let mut inner = item. inner . borrow_mut ( ) ;
219+ unsafe { SetParent ( inner. view . as_widget ( ) . as_win32 ( ) , HWND_MESSAGE ) } ;
220+ inner. index = None ;
198221 self . reset_indices ( ) ;
199222 if need_reselect {
200223 self . set_selection ( 0 ) ?;
@@ -213,7 +236,9 @@ impl TabView {
213236 pub fn clear ( & mut self ) -> Result < ( ) > {
214237 self . handle . send_message ( TCM_DELETEALLITEMS , 0 , 0 ) ;
215238 for item in self . views . drain ( ..) {
216- item. inner . borrow_mut ( ) . index = None ;
239+ let mut inner = item. inner . borrow_mut ( ) ;
240+ unsafe { SetParent ( inner. view . as_widget ( ) . as_win32 ( ) , HWND_MESSAGE ) } ;
241+ inner. index = None ;
217242 }
218243 Ok ( ( ) )
219244 }
@@ -234,10 +259,10 @@ pub struct TabViewItem {
234259}
235260
236261impl TabViewItem {
237- pub fn new ( parent : & TabView ) -> Result < Self > {
262+ pub fn new ( ) -> Result < Self > {
238263 Ok ( Self {
239264 inner : Rc :: new ( RefCell :: new ( TabViewItemInner {
240- view : View :: new_hidden ( parent . as_widget ( ) . as_win32 ( ) ) ?,
265+ view : View :: new_hidden ( HWND_MESSAGE ) ?,
241266 title : String :: new ( ) ,
242267 index : None ,
243268 } ) ) ,
0 commit comments