msi: Make the MSI SelectionTree control do something useful.
This commit is contained in:
parent
b54e9e94e9
commit
848f67e13e
|
@ -1,6 +1,9 @@
|
||||||
Makefile
|
Makefile
|
||||||
cond.tab.c
|
cond.tab.c
|
||||||
cond.tab.h
|
cond.tab.h
|
||||||
|
instabsent.bmp
|
||||||
|
instadvert.bmp
|
||||||
|
instlocal.bmp
|
||||||
libmsi.def
|
libmsi.def
|
||||||
msi.res
|
msi.res
|
||||||
sql.tab.c
|
sql.tab.c
|
||||||
|
|
|
@ -4,7 +4,7 @@ SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = msi.dll
|
MODULE = msi.dll
|
||||||
IMPORTLIB = libmsi.$(IMPLIBEXT)
|
IMPORTLIB = libmsi.$(IMPLIBEXT)
|
||||||
IMPORTS = shell32 shlwapi cabinet oleaut32 ole32 version user32 gdi32 advapi32 kernel32
|
IMPORTS = comctl32 shell32 shlwapi cabinet oleaut32 ole32 version user32 gdi32 advapi32 kernel32
|
||||||
EXTRALIBS = -luuid $(LIBUNICODE)
|
EXTRALIBS = -luuid $(LIBUNICODE)
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
|
@ -43,6 +43,11 @@ C_SRCS = \
|
||||||
where.c
|
where.c
|
||||||
|
|
||||||
RC_SRCS = msi.rc
|
RC_SRCS = msi.rc
|
||||||
|
RC_BINSRC = msi.rc
|
||||||
|
RC_BINARIES = \
|
||||||
|
instabsent.bmp \
|
||||||
|
instadvert.bmp \
|
||||||
|
instlocal.bmp
|
||||||
|
|
||||||
EXTRA_SRCS = sql.y cond.y
|
EXTRA_SRCS = sql.y cond.y
|
||||||
EXTRA_OBJS = sql.tab.o cond.tab.o
|
EXTRA_OBJS = sql.tab.o cond.tab.o
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||||
|
|
||||||
|
|
||||||
|
extern HINSTANCE msi_hInstance;
|
||||||
|
|
||||||
struct msi_control_tag;
|
struct msi_control_tag;
|
||||||
typedef struct msi_control_tag msi_control;
|
typedef struct msi_control_tag msi_control;
|
||||||
typedef UINT (*msi_handler)( msi_dialog *, msi_control *, WPARAM );
|
typedef UINT (*msi_handler)( msi_dialog *, msi_control *, WPARAM );
|
||||||
|
@ -1387,9 +1389,145 @@ static UINT msi_dialog_radiogroup_control( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
|
|
||||||
/******************** Selection Tree ***************************************/
|
/******************** Selection Tree ***************************************/
|
||||||
|
|
||||||
|
struct msi_selection_tree_info
|
||||||
|
{
|
||||||
|
msi_dialog *dialog;
|
||||||
|
HWND hwnd;
|
||||||
|
WNDPROC oldproc;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
msi_dialog_tv_add_child_features( MSIPACKAGE *package, HWND hwnd,
|
msi_seltree_sync_item_state( HWND hwnd, MSIFEATURE *feature, HTREEITEM hItem )
|
||||||
LPCWSTR parent, HTREEITEM hParent )
|
{
|
||||||
|
TVITEMW tvi;
|
||||||
|
|
||||||
|
TRACE("Feature %s -> %d %d %d\n", debugstr_w(feature->Title),
|
||||||
|
feature->Installed, feature->Action, feature->ActionRequest);
|
||||||
|
|
||||||
|
tvi.mask = TVIF_STATE;
|
||||||
|
tvi.hItem = hItem;
|
||||||
|
tvi.state = INDEXTOSTATEIMAGEMASK( feature->Action );
|
||||||
|
tvi.stateMask = TVIS_STATEIMAGEMASK;
|
||||||
|
|
||||||
|
SendMessageW( hwnd, TVM_SETITEMW, 0, (LPARAM) &tvi );
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT
|
||||||
|
msi_seltree_popup_menu( HWND hwnd, INT x, INT y )
|
||||||
|
{
|
||||||
|
HMENU hMenu;
|
||||||
|
INT r;
|
||||||
|
|
||||||
|
/* create a menu to display */
|
||||||
|
hMenu = CreatePopupMenu();
|
||||||
|
|
||||||
|
/* FIXME: load strings from resources */
|
||||||
|
AppendMenuA( hMenu, MF_ENABLED, INSTALLSTATE_LOCAL, "Install feature locally");
|
||||||
|
AppendMenuA( hMenu, MF_GRAYED, 0x1000, "Install entire feature");
|
||||||
|
AppendMenuA( hMenu, MF_ENABLED, INSTALLSTATE_ADVERTISED, "Install on demand");
|
||||||
|
AppendMenuA( hMenu, MF_ENABLED, INSTALLSTATE_ABSENT, "Don't install");
|
||||||
|
r = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
|
||||||
|
x, y, 0, hwnd, NULL );
|
||||||
|
DestroyMenu( hMenu );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MSIFEATURE *
|
||||||
|
msi_seltree_feature_from_item( HWND hwnd, HTREEITEM hItem )
|
||||||
|
{
|
||||||
|
TVITEMW tvi;
|
||||||
|
|
||||||
|
/* get the feature from the item */
|
||||||
|
memset( &tvi, 0, sizeof tvi );
|
||||||
|
tvi.hItem = hItem;
|
||||||
|
tvi.mask = TVIF_PARAM | TVIF_HANDLE;
|
||||||
|
SendMessageW( hwnd, TVM_GETITEMW, 0, (LPARAM) &tvi );
|
||||||
|
|
||||||
|
return (MSIFEATURE*) tvi.lParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT
|
||||||
|
msi_seltree_menu( HWND hwnd, HTREEITEM hItem )
|
||||||
|
{
|
||||||
|
MSIFEATURE *feature;
|
||||||
|
union {
|
||||||
|
RECT rc;
|
||||||
|
POINT pt[2];
|
||||||
|
HTREEITEM hItem;
|
||||||
|
} u;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
|
feature = msi_seltree_feature_from_item( hwnd, hItem );
|
||||||
|
if (!feature)
|
||||||
|
{
|
||||||
|
ERR("item %p feature was NULL\n", hItem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the item's rectangle to put the menu just below it */
|
||||||
|
u.hItem = hItem;
|
||||||
|
SendMessageW( hwnd, TVM_GETITEMRECT, 0, (LPARAM) &u.rc );
|
||||||
|
MapWindowPoints( hwnd, NULL, u.pt, 2 );
|
||||||
|
|
||||||
|
r = msi_seltree_popup_menu( hwnd, u.rc.left, u.rc.top );
|
||||||
|
|
||||||
|
switch (r)
|
||||||
|
{
|
||||||
|
case INSTALLSTATE_LOCAL:
|
||||||
|
case INSTALLSTATE_ADVERTISED:
|
||||||
|
case INSTALLSTATE_ABSENT:
|
||||||
|
feature->ActionRequest = r;
|
||||||
|
feature->Action = r;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FIXME("select feature and all children\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update */
|
||||||
|
msi_seltree_sync_item_state( hwnd, feature, hItem );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT WINAPI
|
||||||
|
MSISelectionTree_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
struct msi_selection_tree_info *info;
|
||||||
|
TVHITTESTINFO tvhti;
|
||||||
|
HRESULT r;
|
||||||
|
|
||||||
|
TRACE("%p %04x %08x %08lx\n", hWnd, msg, wParam, lParam);
|
||||||
|
|
||||||
|
info = GetPropW(hWnd, szButtonData);
|
||||||
|
|
||||||
|
switch( msg )
|
||||||
|
{
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
tvhti.pt.x = LOWORD( lParam );
|
||||||
|
tvhti.pt.y = HIWORD( lParam );
|
||||||
|
tvhti.flags = 0;
|
||||||
|
tvhti.hItem = 0;
|
||||||
|
r = CallWindowProcW(info->oldproc, hWnd, TVM_HITTEST, 0, (LPARAM) &tvhti );
|
||||||
|
if (tvhti.flags & TVHT_ONITEMSTATEICON)
|
||||||
|
return msi_seltree_menu( hWnd, tvhti.hItem );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = CallWindowProcW(info->oldproc, hWnd, msg, wParam, lParam);
|
||||||
|
|
||||||
|
switch( msg )
|
||||||
|
{
|
||||||
|
case WM_NCDESTROY:
|
||||||
|
msi_free( info );
|
||||||
|
RemovePropW( hWnd, szButtonData );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
msi_seltree_add_child_features( MSIPACKAGE *package, HWND hwnd,
|
||||||
|
LPCWSTR parent, HTREEITEM hParent )
|
||||||
{
|
{
|
||||||
MSIFEATURE *feature;
|
MSIFEATURE *feature;
|
||||||
TVINSERTSTRUCTW tvis;
|
TVINSERTSTRUCTW tvis;
|
||||||
|
@ -1406,38 +1544,90 @@ msi_dialog_tv_add_child_features( MSIPACKAGE *package, HWND hwnd,
|
||||||
memset( &tvis, 0, sizeof tvis );
|
memset( &tvis, 0, sizeof tvis );
|
||||||
tvis.hParent = hParent;
|
tvis.hParent = hParent;
|
||||||
tvis.hInsertAfter = TVI_SORT;
|
tvis.hInsertAfter = TVI_SORT;
|
||||||
if (feature->Title)
|
tvis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
|
||||||
{
|
tvis.u.item.pszText = feature->Title;
|
||||||
tvis.u.item.mask = TVIF_TEXT;
|
|
||||||
tvis.u.item.pszText = feature->Title;
|
|
||||||
}
|
|
||||||
tvis.u.item.lParam = (LPARAM) feature;
|
tvis.u.item.lParam = (LPARAM) feature;
|
||||||
|
|
||||||
hitem = (HTREEITEM) SendMessageW( hwnd, TVM_INSERTITEMW, 0, (LPARAM) &tvis );
|
hitem = (HTREEITEM) SendMessageW( hwnd, TVM_INSERTITEMW, 0, (LPARAM) &tvis );
|
||||||
if (!hitem)
|
if (!hitem)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
msi_dialog_tv_add_child_features( package, hwnd,
|
msi_seltree_sync_item_state( hwnd, feature, hitem );
|
||||||
feature->Feature, hitem );
|
msi_seltree_add_child_features( package, hwnd,
|
||||||
|
feature->Feature, hitem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msi_seltree_create_imagelist( HWND hwnd )
|
||||||
|
{
|
||||||
|
const int bm_width = 32, bm_height = 16, bm_count = 3;
|
||||||
|
const int bm_resource = 0x1001;
|
||||||
|
HIMAGELIST himl;
|
||||||
|
int i;
|
||||||
|
HBITMAP hbmp;
|
||||||
|
|
||||||
|
himl = ImageList_Create( bm_width, bm_height, FALSE, 4, 0 );
|
||||||
|
if (!himl)
|
||||||
|
{
|
||||||
|
ERR("failed to create image list\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<bm_count; i++)
|
||||||
|
{
|
||||||
|
hbmp = LoadBitmapW( msi_hInstance, MAKEINTRESOURCEW(i+bm_resource) );
|
||||||
|
if (!hbmp)
|
||||||
|
{
|
||||||
|
ERR("failed to load bitmap %d\n", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a dummy bitmap at offset zero because the treeview
|
||||||
|
* can't use it as a state mask (zero means no user state).
|
||||||
|
*/
|
||||||
|
if (!i)
|
||||||
|
ImageList_Add( himl, hbmp, NULL );
|
||||||
|
|
||||||
|
ImageList_Add( himl, hbmp, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageW( hwnd, TVM_SETIMAGELIST, TVSIL_STATE, (LPARAM)himl );
|
||||||
|
}
|
||||||
|
|
||||||
static UINT msi_dialog_selection_tree( msi_dialog *dialog, MSIRECORD *rec )
|
static UINT msi_dialog_selection_tree( msi_dialog *dialog, MSIRECORD *rec )
|
||||||
{
|
{
|
||||||
msi_control *control;
|
msi_control *control;
|
||||||
LPCWSTR prop;
|
LPCWSTR prop;
|
||||||
LPWSTR val;
|
|
||||||
MSIPACKAGE *package = dialog->package;
|
MSIPACKAGE *package = dialog->package;
|
||||||
|
DWORD style;
|
||||||
|
struct msi_selection_tree_info *info;
|
||||||
|
|
||||||
prop = MSI_RecordGetString( rec, 9 );
|
info = msi_alloc( sizeof *info );
|
||||||
val = msi_dup_property( package, prop );
|
if (!info)
|
||||||
control = msi_dialog_add_control( dialog, rec, WC_TREEVIEWW,
|
|
||||||
TVS_HASBUTTONS | WS_GROUP | WS_VSCROLL );
|
|
||||||
if (!control)
|
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
msi_dialog_tv_add_child_features( package, control->hwnd, NULL, NULL );
|
/* create the treeview control */
|
||||||
|
prop = MSI_RecordGetString( rec, 9 );
|
||||||
|
style = TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT;
|
||||||
|
style |= WS_GROUP | WS_VSCROLL;
|
||||||
|
control = msi_dialog_add_control( dialog, rec, WC_TREEVIEWW, style );
|
||||||
|
if (!control)
|
||||||
|
{
|
||||||
|
msi_free(info);
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
msi_free( val );
|
/* subclass */
|
||||||
|
info->dialog = dialog;
|
||||||
|
info->hwnd = control->hwnd;
|
||||||
|
info->oldproc = (WNDPROC) SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC,
|
||||||
|
(LONG_PTR)MSISelectionTree_WndProc );
|
||||||
|
SetPropW( control->hwnd, szButtonData, info );
|
||||||
|
|
||||||
|
/* initialize it */
|
||||||
|
msi_seltree_create_imagelist( control->hwnd );
|
||||||
|
msi_seltree_add_child_features( package, control->hwnd, NULL, NULL );
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,3 +37,90 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
#include "msi_Nl.rc"
|
#include "msi_Nl.rc"
|
||||||
#include "msi_No.rc"
|
#include "msi_No.rc"
|
||||||
#include "msi_Pt.rc"
|
#include "msi_Pt.rc"
|
||||||
|
|
||||||
|
/* BINRES instadvert.bmp */
|
||||||
|
0x1001 BITMAP instadvert.bmp
|
||||||
|
/* {
|
||||||
|
'42 4D 76 01 00 00 00 00 00 00 76 00 00 00 28 00'
|
||||||
|
'00 00 20 00 00 00 10 00 00 00 01 00 04 00 00 00'
|
||||||
|
'00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
|
||||||
|
'00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
|
||||||
|
'00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF'
|
||||||
|
'00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
|
||||||
|
'00 00 FF FF FF 00 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 70 00 00 07 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 70 03 33 B3 30 07 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 00 B3 33 33 33 00 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 03 33 B3 A3 B3 30 77 77 77'
|
||||||
|
'77 77 07 77 77 77 70 33 33 33 33 33 B3 07 77 77'
|
||||||
|
'77 70 00 77 77 77 70 33 B3 30 03 33 33 07 77 77'
|
||||||
|
'77 00 00 07 77 77 70 33 33 00 00 3B 33 07 77 77'
|
||||||
|
'70 00 00 00 77 77 70 33 B3 30 0B 33 3B 07 77 77'
|
||||||
|
'00 00 00 00 07 77 70 3B 3A 33 33 33 33 07 77 70'
|
||||||
|
'00 00 00 00 00 77 77 03 3B 3B 3A 3B 30 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 00 33 33 3B 33 00 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 70 03 B3 33 30 07 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 70 00 00 07 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77'
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* BINRES instabsent.bmp */
|
||||||
|
0x1002 BITMAP instabsent.bmp
|
||||||
|
/* {
|
||||||
|
'42 4D 76 01 00 00 00 00 00 00 76 00 00 00 28 00'
|
||||||
|
'00 00 20 00 00 00 10 00 00 00 01 00 04 00 00 00'
|
||||||
|
'00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
|
||||||
|
'00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
|
||||||
|
'00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF'
|
||||||
|
'00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
|
||||||
|
'00 00 FF FF FF 00 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 70 07 77 77 77 77 70 07 77 77'
|
||||||
|
'77 77 77 77 77 77 70 00 77 77 77 77 00 07 77 77'
|
||||||
|
'77 77 77 77 77 77 77 00 07 77 77 70 00 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 70 00 77 77 00 07 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 00 07 70 00 77 77 77 77'
|
||||||
|
'77 77 07 77 77 77 77 77 70 00 00 07 77 77 77 77'
|
||||||
|
'77 70 00 77 77 77 77 77 77 00 00 77 77 77 77 77'
|
||||||
|
'77 00 00 07 77 77 77 77 77 00 00 77 77 77 77 77'
|
||||||
|
'70 00 00 00 77 77 77 77 70 00 00 07 77 77 77 77'
|
||||||
|
'00 00 00 00 07 77 77 77 00 07 70 00 77 77 77 70'
|
||||||
|
'00 00 00 00 00 77 77 70 00 77 77 00 07 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 00 07 77 77 70 00 77 77 77'
|
||||||
|
'77 77 77 77 77 77 70 00 77 77 77 77 00 07 77 77'
|
||||||
|
'77 77 77 77 77 77 70 07 77 77 77 77 70 07 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77'
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* BINRES instlocal.bmp */
|
||||||
|
0x1003 BITMAP instlocal.bmp
|
||||||
|
/* {
|
||||||
|
'42 4D 76 01 00 00 00 00 00 00 76 00 00 00 28 00'
|
||||||
|
'00 00 20 00 00 00 10 00 00 00 01 00 04 00 00 00'
|
||||||
|
'00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
|
||||||
|
'00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
|
||||||
|
'00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF'
|
||||||
|
'00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
|
||||||
|
'00 00 FF FF FF 00 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 70 07 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 0F F0 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77 77 70 FF FF 07 77 77 77 77 77'
|
||||||
|
'77 77 07 77 77 77 77 0F F0 0F F0 77 77 77 77 77'
|
||||||
|
'77 70 00 77 77 77 77 0F 07 70 FF 07 77 77 77 77'
|
||||||
|
'77 00 00 07 77 77 77 70 77 77 0F F0 77 77 77 77'
|
||||||
|
'70 00 00 00 77 77 77 77 77 77 70 FF 07 77 77 77'
|
||||||
|
'00 00 00 00 07 77 77 77 77 77 77 0F F0 77 77 70'
|
||||||
|
'00 00 00 00 00 77 77 77 77 77 77 70 FF 07 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 0F F0 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 70 F0 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 77 07 77 77'
|
||||||
|
'77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
|
||||||
|
'77 77 77 77 77 77'
|
||||||
|
} */
|
||||||
|
|
Loading…
Reference in New Issue