Расширение оболочки Explorer (контекстное меню для проводника)
Всем известны программы winrar или winamp , которые умеют добавлять свой пункт меню в контекстное меню. При клике по этому пункту , в программу передается\передаются нужные файлы. Когда я только начинал программировать, то обходился более простой реализацией: добавлял в реестр ключ для передачи файлов через командную строку. Но данный способ хорош только для простых программ вроде notepad (то есть когда нужно передать 1 файл). Когда нужно передать несколько файлов, то командная строка для каждого переданного файла запускает новые копии программы. Конечно при добротных костылях можно реализовать и этот способ (и я так уже делал), но все это будет выглядеть очень некрасиво, да и работать медленно при больших кол-вах переданных файлов. Более того данный способ не дает всей широты возможностей , например нет возможности добавить свою иконку. Майкрософт создавая проводник (explorer) , внедрили возможность его расширения. Код ниже как раз показывает как можно создать свое расширение explorer (контекстное меню для проводника). Я не знаю будет ли работать код в 64х битной системе, но на моей 32х битной кажется работает нормально. Чтобы не засорять сервер лишними архивами или файлами, я поместил изображение бинарно в код DLL. То есть данный код самодостаточен, просто скомпилируйте DLL под любым именем. Для тестирования запустите CMD под администратором, пройдите в папку расположения вашей DLL и введите в CMD следующее:
regsvr32 ваше_имя.dll (это для регистрации пункта меню)
При успешной регистрации , должно получиться примерно следующее:
Ну а дальше просто выделяете любой файл\файлы в проводнике и щелкаете правой кнопкой мыши. Должно появится примерно следующее:
При выборе нашего пункта, появится messageBox с именами выбранных файлов.
Да... на папках не работает. Чтобы можно было выделять и папки, нужно в функцию регистрации и удаления регистрации добавлять соотвествующие ключи для реестра.
Когда захотите удалить меню, наберите: regsvr32 /u ваше_имя.dll
Чтобы удалить dll , нужно либо перезагрузить explorer либо перезагрузить компьютер. Вот пожалуй и все!
Платформа: Windows (тестировалась на windows 7 , 32х бит)
Компилятор:
freebasic 1.03.0 , но должен работать и более старых версиях
Автор: Станислав
Будинов
#DEFINE _UNICODE #DEFINE ID_SHELLTEST_C 1 #INCLUDE Once "windows.bi" #INCLUDE Once "crt.bi" #INCLUDE Once "win/ocidl.bi" #INCLUDE Once "win/shlobj.bi" #INCLUDE Once "win/olectl.bi" Static Shared CLSIDS_POINT As ZString*2048 = "{9D267B24-B27F-46E1-9062-6FC17716095E}" Dim Shared CLSID_POINT As IID=Type(&h9D267B24, &hB27F, &h46E1, {&h90, &h62, &h6F, &hC1, &h77, &h16, &h09, &h5E}) Dim Shared nRefDll As UINT Dim Shared As Integer nNumberFileSelect Redim Shared As ZString*MAX_PATH ArrayFiles() Dim Shared As IContextMenuVtbl pIContextMenuVtbl Dim Shared As IShellExtInitVtbl pIShellExtInitVtbl Extern data_1(0 To 1654-1) As Ubyte Dim pBi As BITMAPINFO Ptr Dim Shared bmpMenu As HBITMAP Dim pBih As BITMAPFILEHEADER Ptr = Cast( Any Ptr, @data_1(0) ) pBi = Cast(BITMAPINFO Ptr, pBih + 1) Dim As HDC hdc = GetDC( 0 ) bmpMenu = CreateDIBitmap( hdc, _ @pBi->bmiHeader, _ CBM_INIT, _ Cast(Byte Ptr, pBih) + pBih->bfOffBits, _ pBi, _ DIB_RGB_COLORS ) ReleaseDC(0,hdc) Type ConText_ClassFactory icf As IClassFactory cRef As Integer End Type Type ConTextMenu_Class cm As IContextMenu si As IShellExtInit cRef As Integer End Type Function IContextMenu_QueryInterface_(pIm As IContextMenu Ptr, iid As REFIID, ppv As LPVOID Ptr) As HRESULT Dim pThis As ConTextMenu_Class Ptr pThis = Cast(ConTextMenu_Class Ptr,pIm) If memcmp(iid, @IID_IUnknown, Sizeof(GUID))=0 Or memcmp(iid, @IID_IContextMenu, Sizeof(GUID))=0 Then *ppv = pThis pThis->cRef+=1 Return S_OK Elseif memcmp(iid, @IID_IShellExtInit, Sizeof(GUID))=0 Then *ppv = @(pThis->si) pThis->cRef+=1 Return S_OK End If ppv = NULL Return E_NOINTERFACE End Function Function IContextMenu_AddRef_(pIm As IContextMenu Ptr) As Ulong Dim pThis As ConTextMenu_Class Ptr pThis = Cast(ConTextMenu_Class Ptr,pIm) pThis->cRef +=1 Return pThis->cRef End Function Function IContextMenu_Release_(pIm As IContextMenu Ptr) As Ulong Dim pThis As ConTextMenu_Class Ptr pThis = Cast(ConTextMenu_Class Ptr,pIm) pThis->cRef-=1 If pThis->cRef = 0 Then Deallocate(pIm) nRefDll -=1 Return 0 End If Return pThis->cRef End Function Function IContextMenu_QueryContextMenu_( pIm As IContextMenu Ptr, hmenu As HMENU, indexMenu As Uinteger, idCmdFirst As Uinteger, idCmdLast As Uinteger, uFlags As Uinteger) As HRESULT If (uFlags And CMF_DEFAULTONLY) Then Return MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_NULL,0) Endif InsertMenu(hMenu,1, MF_STRING Or MF_BYPOSITION, (idCmdFirst + ID_SHELLTEST_C),("Test item FreebasicShell")) SetMenuItemBitmaps(hMenu,1,MF_BITMAP Or MF_BYPOSITION,bmpMenu,bmpMenu) Return MAKE_HRESULT(0, FACILITY_NULL, ID_SHELLTEST_C + 1) End Function Function IContextMenu_GetCommandString_( pIm As IContextMenu Ptr, idCmd As Uinteger, uFlags As Uinteger, pwReserved As PUINT, pszName As LPSTR, cchMax As Uinteger) As Integer Return E_NOTIMPL End Function Function IContextMenu_InvokeCommand_( pIm As IContextMenu Ptr, pici As LPCMINVOKECOMMANDINFO) As HRESULT Select Case Loword(pici->lpVerb) Case ID_SHELLTEST_C Dim As String szValue If nNumberFileSelect>=1 Then For i As Integer = 0 To nNumberFileSelect-1 szValue &= (ArrayFiles(i) & !"\r\n" ) Next MessageBox(NULL, szValue ,"Selected files", MB_OK + MB_ICONINFORMATION) Endif Return S_OK Case Else Return E_FAIL End Select End Function Function CShellInitExt_QueryInterface_(pThis As IShellExtInit Ptr, riid As REFIID , ppv As LPVOID Ptr) As HRESULT Return Cast(IContextMenu Ptr ,pThis - 1)->lpVtbl->QueryInterface(Cast(IContextMenu Ptr ,(pThis - 1)),riid,ppv) End Function Function CShellInitExt_AddRef_(pThis As IShellExtInit Ptr)As Ulong Return Cast(IContextMenu Ptr ,pThis - 1)->lpVtbl->AddRef(Cast(IContextMenu Ptr ,(pThis - 1))) End Function Function CShellInitExt_Release_( pThis As IShellExtInit Ptr) As Ulong Return Cast(IContextMenu Ptr ,pThis - 1)->lpVtbl->Release(Cast(IContextMenu Ptr ,(pThis - 1))) End Function Function CShellInitExt_Initialize_(Byval pIShell As IShellExtInit Ptr,Byval pidlFolder As LPCITEMIDLIST,Byval pdtobj As LPDATAOBJECT, Byval hkeyProgID As HKEY)As HRESULT If pdtobj <>0 Then Dim fe As FORMATETC fe.cfFormat = CF_HDROP fe.dwAspect = DVASPECT_CONTENT fe.lindex = -1 fe.tymed = TYMED_HGLOBAL Dim medium As STGMEDIUM If pdtobj->lpVtbl->GetData(pdtobj,@fe, @medium)=S_OK Then Var uCount = DragQueryFile(medium.hGlobal, -1, 0, 0) nNumberFileSelect = uCount Redim As ZString*MAX_PATH ArrayFiles(uCount) If uCount>=1 Then For dd As Integer=0 To uCount-1 Dim As ZString*MAX_PATH m_szFile DragQueryFile(medium.hGlobal, dd, m_szFile, MAX_PATH) If Len(m_szFile)=0 Then uCount = 0 Else ArrayFiles(dd) = m_szFile Endif Next Endif ReleaseStgMedium(@medium) If uCount>=1 Then Return S_OK Endif Endif Endif Return S_FALSE End Function pIShellExtInitVtbl = Type(@CShellInitExt_QueryInterface_, _ @CShellInitExt_AddRef_, _ @CShellInitExt_Release_, _ @CShellInitExt_Initialize_) pIContextMenuVtbl = Type(@IContextMenu_QueryInterface_, _ @IContextMenu_AddRef_, _ @IContextMenu_Release_, _ @IContextMenu_QueryContextMenu_ , _ @IContextMenu_InvokeCommand_ , _ @IContextMenu_GetCommandString_ ) Function ClassFactory_CFQueryInterface(pCF As IClassFactory Ptr, iid As REFIID, ppvObject As LPVOID Ptr) As HRESULT Dim pThis As ConText_ClassFactory Ptr pThis = Cast(ConText_ClassFactory Ptr,pCF) If IsEqualIID( iid, @IID_IUnknown) Or IsEqualIID( iid, @IID_IClassFactory) Then *ppvObject = pThis pThis->icf.lpVtbl->AddRef(pCF) Return S_OK End If *ppvObject = NULL Return E_NOINTERFACE End Function Function ClassFactory_CFAddRef(pCF As IClassFactory Ptr) As Ulong Dim pThis As ConText_ClassFactory Ptr pThis = Cast(ConText_ClassFactory Ptr,pCF) pThis->cRef +=1 Return pThis->cRef End Function Function ClassFactory_CFRelease( pCF As IClassFactory Ptr) As Ulong Dim pThis As ConText_ClassFactory Ptr pThis = Cast(ConText_ClassFactory Ptr,pCF) pThis->cRef -=1 If pThis->cRef = 0 Then Deallocate( pThis ) pThis = 0 nRefDll -=1 Return 0 End If Return pThis->cRef End Function Function ClassFactory_CFCreateInstance( pICF As IClassFactory Ptr, pUnkOuter As IUnknown Ptr, riid As REFIID, ppvObject As LPVOID Ptr) As HRESULT Dim pThis As ConText_ClassFactory Ptr Dim pCM As ConTextMenu_Class Ptr pThis = Cast(ConText_ClassFactory Ptr,pICF) If pUnkOuter <> NULL Then Return CLASS_E_NOAGGREGATION End If pCM = Cast(ConTextMenu_Class Ptr,Callocate(Sizeof(ConTextMenu_Class))) If NULL = pCM Then Return E_OUTOFMEMORY End If pCM->cm.lpVtbl = @pIContextMenuVtbl pCM->si.lpVtbl = @pIShellExtInitVtbl pCM->cRef = 1 nRefDll +=1 Var hr = pCM->cm.lpVtbl->QueryInterface(@(pCM->cm), riid, ppvObject) If hr <> S_OK Then Deallocate( pCM ) Return E_NOINTERFACE End If pCM->cm.lpVtbl->Release(@(pCM->cm)) Return hr End Function Function ClassFactory_CFLockServer( pICF As IClassFactory Ptr, fLock As BOOL) As HRESULT Return E_NOTIMPL End Function Static Shared As IClassFactoryVtbl pIClassFactoryVtbl = Type(@ClassFactory_CFQueryInterface, _ @ClassFactory_CFAddRef, _ @ClassFactory_CFRelease, _ @ClassFactory_CFCreateInstance, _ @ClassFactory_CFLockServer) Extern "windows-ms" #Undef DllRegisterServer #Undef DllUnregisterServer Function DllRegisterServer() As Long Export Dim As HKEY hKey1 If RegCreateKeyEx(HKEY_CLASSES_ROOT, "*\shellex\ContextMenuHandlers\FreeBasicShell", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, Null, @hKey1, 0)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS RegSetValueEx(hKey1, "", 0, REG_SZ, @"{9D267B24-B27F-46E1-9062-6FC17716095E}", 38) If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 If RegCreateKeyEx(HKEY_CLASSES_ROOT, "FreeBasicShell\shellex\ContextMenuHandlers", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, Null, @hKey1, 0)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS RegSetValueEx(hKey1, "", 0, REG_SZ, @"{9D267B24-B27F-46E1-9062-6FC17716095E}", 38) If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 If RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, Null, @hKey1, 0)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS RegSetValueEx(hKey1, "{9D267B24-B27F-46E1-9062-6FC17716095E}", 0, REG_SZ, @"FreeBasicShell", 15) If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 Dim As ZString*MAX_PATH szBuffer Dim As HMODULE hmod GetModuleHandleEx(4,Cast(LPSTR,@DllRegisterServer) , @hMod) If GetModuleFileName(hMod, szBuffer, MAX_PATH)<>0 Then If RegCreateKeyEx(HKEY_CLASSES_ROOT, "CLSID\{9D267B24-B27F-46E1-9062-6FC17716095E}", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, Null, @hKey1, 0)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS RegSetValueEx(hKey1, "", 0, REG_SZ, @"FreeBasicShell", 15) If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 If RegCreateKeyEx(HKEY_CLASSES_ROOT, "CLSID\{9D267B24-B27F-46E1-9062-6FC17716095E}\InProcServer32", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, Null, @hKey1, 0)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS RegSetValueEx(hKey1, "", 0, REG_SZ, @szBuffer, Len(szBuffer)+1) RegSetValueEx(hKey1, "ThreadingModel", 0, REG_SZ, @"Apartment", 10) If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 Else Return SELFREG_E_CLASS Endif Return S_OK End Function Function DllUnregisterServer()As HRESULT Export Dim As HKEY hkey1 If RegDeleteKey(HKEY_CLASSES_ROOT, "*\shellex\ContextMenuHandlers\FreeBasicShell")<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If RegDeleteKey(HKEY_CLASSES_ROOT, "FreeBasicShell\shellex\ContextMenuHandlers")<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If RegDeleteKey(HKEY_CLASSES_ROOT, "FreeBasicShell\shellex")<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If RegDeleteKey(HKEY_CLASSES_ROOT, "FreeBasicShell")<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", 0, KEY_ALL_ACCESS, @hKey1)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If RegDeleteValue(hKey1, "{9D267B24-B27F-46E1-9062-6FC17716095E}")<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 If RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID\{9D267B24-B27F-46E1-9062-6FC17716095E}", 0, KEY_ALL_ACCESS, @hKey1)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If RegDeleteKey(hKey1, "InProcServer32")<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 If RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_ALL_ACCESS, @hKey1)<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If RegDeleteKey(hKey1, "{9D267B24-B27F-46E1-9062-6FC17716095E}")<>ERROR_SUCCESS Then Return SELFREG_E_CLASS If hKey1<>0 Then RegCloseKey(hKey1):hKey1 = 0 Return S_OK End Function #Undef DllCanUnloadNow Function DllCanUnloadNow() As HRESULT Export If nRefDll = 0 Then Return S_OK End If Return S_FALSE End Function #Undef DllGetClassObject Function DllGetClassObject(rclsid As REFCLSID, riid As REFIID , ppv As LPVOID Ptr) As HRESULT Export Dim As ConText_ClassFactory Ptr pCF = NULL If IsEqualCLSID( @CLSID_POINT, rclsid ) Then If pCF = NULL Then pCF = Callocate(Sizeof(pCF)) If pCF = NULL Then Return E_OUTOFMEMORY End If End If pCF->icf.lpVtbl = @(pIClassFactoryVtbl) pCF->cRef = 0 Return ClassFactory_CFQueryInterface(Cast(IClassFactory Ptr,pCF), riid, ppv ) End If Return CLASS_E_CLASSNOTAVAILABLE End Function End Extern Dim Shared data_1(0 To 1654-1) As Ubyte = { _ &h42,&h4D,&h76,&h6,&h0,&h0,&h0,&h0,&h0,&h0,&h36,&h4,&h0,&h0,&h28,&h0,&h0,&h0,&h18,&h0,&h0,&h0,&h18,&h0,&h0,&h0,&h1,&h0,&h8,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&hC4,&hE,&h0,&h0,&hC4,&hE,&h0,&h0,&h0,&h1,&h0,&h0,&h0,&h1,&h0,&h0,&h0,&h0,&h0,&hFF,&h1,&h1,&h4,&hFF, _ &h4,&h4,&h8,&hFF,&h6,&h6,&hC,&hFF,&h8,&h9,&h10,&hFF,&hA,&hC,&h14,&hFF,&hD,&hD,&h18,&hFF,&hF,&h10,&h1C,&hFF,&h11,&h12,&h20,&hFF,&h13,&h15,&h24, _ &hFF,&h16,&h18,&h28,&hFF,&h18,&h1A,&h2C,&hFF,&h1A,&h1C,&h30,&hFF,&h1D,&h1E,&h34,&hFF,&h1F,&h21,&h38,&hFF,&h21,&h24,&h3C,&hFF,&h23,&h26,&h40,&hFF,&h26,&h28, _ &h44,&hFF,&h2A,&h2D,&h4C,&hFF,&h2C,&h30,&h50,&hFF,&h2F,&h32,&h54,&hFF,&h31,&h34,&h58,&hFF,&h33,&h37,&h5C,&hFF,&h36,&h39,&h60,&hFF,&h3A,&h3E,&h68,&hFF,&h3C, _ &h40,&h6C,&hFF,&h3F,&h43,&h70,&hFF,&h41,&h45,&h74,&hFF,&h43,&h48,&h78,&hFF,&h46,&h4A,&h7C,&hFF,&h49,&h4E,&h83,&hFF,&h4E,&h53,&h8B,&hFF,&h50,&h55,&h8F,&hFF, _ &h53,&h58,&h93,&hFF,&h55,&h5A,&h97,&hFF,&h57,&h5D,&h9B,&hFF,&h5C,&h61,&hA3,&hFF,&h5E,&h64,&hA7,&hFF,&h60,&h66,&hAB,&hFF,&h65,&h6B,&hB3,&hFF,&h67,&h6E,&hB7, _ &hFF,&h69,&h70,&hBB,&hFF,&h6E,&h75,&hC3,&hFF,&h70,&h77,&hC7,&hFF,&h72,&h7A,&hCB,&hFF,&h75,&h7C,&hCF,&hFF,&h77,&h7E,&hD3,&hFF,&h79,&h81,&hD7,&hFF,&h7E,&h86, _ &hDF,&hFF,&h80,&h88,&hE3,&hFF,&h82,&h8B,&hE7,&hFF,&h85,&h8D,&hEB,&hFF,&h87,&h8F,&hEF,&hFF,&h89,&h92,&hF3,&hFF,&h8B,&h94,&hF7,&hFF,&h8E,&h97,&hFB,&hFF,&h91, _ &h9A,&hFF,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF, _ &h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0, _ &hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0, _ &h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0, _ &h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF, _ &h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0, _ &hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0, _ &h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0, _ &h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF, _ &h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0, _ &hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0, _ &h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0, _ &h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF, _ &h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0, _ &hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0, _ &h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0, _ &h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF, _ &h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0, _ &hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0, _ &h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0, _ &h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF, _ &h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0, _ &hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0, _ &h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0, _ &h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF, _ &h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&hFF,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&hD,&h21,&h6,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h17,&hC,&h1D,&h30,&h29,&h1E,&h4,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h27,&h38,&h10,&h0,&h0,&h0,&h0,&h0,&h0,&h5,&h38,&h2A,&h12,&h2F,&h38,&h38, _ &h32,&h12,&h0,&h0,&h0,&h0,&h0,&h0,&h28,&h38,&h15,&h0,&h0,&h0,&h0,&h0,&h0,&h5,&h38,&h36,&h0,&h0,&h1,&h15,&h33,&h37,&h14,&h0,&h0,&h0,&h0, _ &h0,&h23,&h38,&h17,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h32,&h38,&h5,&h0,&h0,&h0,&hA,&h34,&h37,&h3,&h0,&h0,&h0,&h0,&h1D,&h38,&h1F,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h28,&h38,&hC,&h0,&h0,&h0,&h0,&h27,&h38,&h12,&h0,&h0,&h0,&h0,&h16,&h38,&h38,&h35,&h2C,&h26,&h20,&h12,&h0,&h0,&h21,&h38,&h13, _ &h11,&h14,&h5,&h13,&h36,&h38,&h7,&h0,&h0,&h0,&h0,&hE,&h38,&h34,&h2A,&h32,&h38,&h38,&h37,&h4,&h0,&h1B,&h38,&h19,&h2D,&h38,&h38,&h38,&h37,&h1E,&h0, _ &h0,&h0,&h0,&h0,&h6,&h38,&h2E,&h0,&h0,&h3,&hC,&h7,&h0,&h0,&h12,&h38,&h21,&h2,&h1B,&h35,&h38,&h1A,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h34,&h37, _ &h2,&h0,&h0,&h0,&h0,&h0,&h0,&h9,&h38,&h28,&h0,&h0,&h8,&h2B,&h38,&h1A,&h0,&h0,&h0,&h0,&h0,&h0,&h2C,&h38,&hC,&h0,&h0,&h0,&h0,&h0,&h0, _ &h16,&h38,&h31,&h0,&h0,&h0,&h3,&h31,&h38,&h8,&h0,&h0,&h0,&h0,&h0,&h2A,&h38,&h2D,&h21,&h1C,&h17,&h17,&hF,&h4,&h35,&h38,&h38,&h22,&hE,&h8,&hA, _ &h2F,&h38,&h16,&h0,&h0,&h0,&h0,&h0,&h25,&h38,&h38,&h38,&h38,&h38,&h38,&h36,&h5,&hB,&h24,&h35,&h38,&h38,&h38,&h38,&h38,&h2E,&h5,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h5,&hC,&h10,&h17,&hB,&h0,&h0,&h0,&h0,&h6,&h10,&h18,&h1D,&hF,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0, _ &h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0,&h0 }