アイコンサムネイルとライブプレビューの実装例(テキストエディター)
タブ型のテキストエディターを作ります。
最終更新:2017/11/21
初版:2017/11/21
HRESULT RegisterTab( [in] HWND hwndTab, [in] HWND hwndMDI ); // メソッドindex値 : 11hwndTab にドキュメントウィンドウのウィンドウハンドルを指定します。
HRESULT SetTabOrder( [in] HWND hwndTab, [in, optional] HWND hwndInsertBefore ); // メソッドindex値 : 13hwndTab にRegisterTab メソッドで登録したドキュメントウィンドウのウィンドウハンドルを指定します。
#define WM_CREATE 0x0001 #define WM_SIZE 0x0005 #define WM_ACTIVATE 0x0006 #define WM_SETTEXT 0x000C #define WM_GETTEXT 0x000D #define WM_GETTEXTLENGTH 0x000E #define WM_SETFONT 0x0030 #define WM_NOTIFY 0x004E #define WM_COMMAND 0x0111 #define WM_PRINT 0x0317 #define WM_PRINTCLIENT 0x0318 #define TCM_GETITEMCOUNT 0x1304 #define TCM_GETITEM 0x1305 #define TCM_SETITEM 0x1306 #define TCM_INSERTITEM 0x1307 #define TCM_DELETEITEM 0x1308 #define TCM_GETCURSEL 0x130B #define TCM_SETCURSEL 0x130C #define TCM_ADJUSTRECT 0x1328 #define TCN_SELCHANGE -551 #define EN_CHANGE 0x0300 #define TCIF_TEXT 0x0001 #define TCIF_PARAM 0x0008 #define WA_ACTIVE 0x00000001 #define MF_INSERT 0x00000000 #define MF_POPUP 0x00000010 #define MF_SEPARATOR 0x00000800 #define WS_CHILD 0x40000000 #define WS_VISIBLE 0x10000000 #define WS_MAXIMIZEBOX 0x0010000 #define WS_SIZEBOX 0x00040000 #define WS_HSCROLL 0x00100000 #define WS_VSCROLL 0x00200000 #define WS_CLIPCHILDREN 0x02000000 #define WS_POPUP 0x80000000 #define WS_EX_NOACTIVATE 0x08000000 #define WS_EX_CLIENTEDGE 0x00000200 #define ES_AUTOHSCROLL 0x00000080 #define ES_AUTOVSCROLL 0x00000040 #define ES_MULTILINE 0x00000004 #define ES_WANTRETURN 0x00001000 #define PRF_CHECKVISIBLE 0x00000001 #define PRF_NONCLIENT 0x00000002 #define PRF_CLIENT 0x00000004 #define PRF_ERASEBKGND 0x00000008 #define PRF_CHILDREN 0x00000010 #define PRF_OWNED 0x00000020 #define SW_HIDE 0x00000000 #define SW_SHOW 0x00000005 #define SW_RESTORE 0x00000009 #define GWL_WNDPROC (-4) #define GWL_STYLE (-16) #define GWL_USERDATA (-21) #define BI_RGB 0 #define HALFTONE 4 #define SRCCOPY 0x00CC0020 #define COLOR_WINDOW 5 #enum IDM_NEW = 100 #enum IDM_OPEN #enum IDM_SAVE #enum IDM_SAVEAS #enum IDM_CLOSE #enum IDM_EXIT #enum IDM_HELPINDEX #enum IDM_ABOUT //TaskbarList #define CLSID_TaskbarList "{56FDF344-FD6D-11d0-958A-006097C9A090}" #define IID_ITaskbarList "{56FDF342-FD6D-11D0-958A-006097C9A090}" #define IID_ITaskbarList2 "{602D4995-B13A-429b-A66E-1935E44F4317}" #define IID_ITaskbarList3 "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}" #usecom ITaskbarList3 IID_ITaskbarList3 CLSID_TaskbarList #comfunc ITaskbarList_HrInit 3 #comfunc ITaskbarList_AddTab 4 int #comfunc ITaskbarList_DeleteTab 5 int #comfunc ITaskbarList_ActivateTab 6 int #comfunc ITaskbarList_SetActiveAlt 7 int #comfunc ITaskbarList2_MarkFullscreenWindow 8 int,int #comfunc ITaskbarList3_SetProgressValue 9 int,double,double #comfunc ITaskbarList3_SetProgressState 10 int,int #comfunc ITaskbarList3_RegisterTab 11 int,int #comfunc ITaskbarList3_UnregisterTab 12 int,int #comfunc ITaskbarList3_SetTabOrder 13 int,int #comfunc ITaskbarList3_SetTabActive 14 int,int #comfunc ITaskbarList3_ThumbBarAddButtons 15 int,int,int #comfunc ITaskbarList3_ThumbBarUpdateButtons 16 int,int,int #comfunc ITaskbarList3_ThumbBarSetImageList 17 int,int,int #comfunc ITaskbarList3_SetOverlayIcon 18 int,int,wstr #comfunc ITaskbarList3_SetThumbnailTooltip 19 int,wstr #comfunc ITaskbarList3_SetThumbnailClip 20 int,int //dwm #uselib "dwmapi.dll" #func DwmSetIconicThumbnail "DwmSetIconicThumbnail" int, int, int #func DwmSetIconicLivePreviewBitmap "DwmSetIconicLivePreviewBitmap" int, int, int, int #func DwmSetWindowAttribute "DwmSetWindowAttribute" int, int, int, int #func DwmInvalidateIconicBitmaps "DwmInvalidateIconicBitmaps" int #define DWM_SIT_DISPLAYFRAME 0x00000001 #define WM_DWMSENDICONICTHUMBNAIL 0x0323 #define WM_DWMSENDICONICLIVEPREVIEWBITMAP 0x0326 #enum DWMWA_NCRENDERING_ENABLED = 1 #enum DWMWA_NCRENDERING_POLICY #enum DWMWA_TRANSITIONS_FORCEDISABLED #enum DWMWA_ALLOW_NCPAINT #enum DWMWA_CAPTION_BUTTON_BOUNDS #enum DWMWA_NONCLIENT_RTL_LAYOUT #enum DWMWA_FORCE_ICONIC_REPRESENTATION #enum DWMWA_FLIP3D_POLICY #enum DWMWA_EXTENDED_FRAME_BOUNDS #enum DWMWA_HAS_ICONIC_BITMAP #enum DWMWA_DISALLOW_PEEK #enum DWMWA_EXCLUDED_FROM_PEEK #enum DWMWA_CLOAK #enum DWMWA_CLOAKED #enum DWMWA_FREEZE_REPRESENTATION #enum DWMWA_LAST
//HSP3.5から対応 #include "user32.as" #include "gdi32.as" #include "kernel32.as" #include "shell32.as" #include "hscallbk.as" #include "define.as" #uselib "" #func MyWndProc "" int, int, int, int setcallbk pDummyWndProc, MyWndProc, *DummyWndProc setcallbk pTabWndProc, MyWndProc, *TabWndProc #define mhwnd callbkarg(0) #define mmsg callbkarg(1) #define mwp callbkarg(2) #define mlp callbkarg(3) #define ctype HIWORD(%1) ((%1>>16)&0xFFFF) #define ctype LOWORD(%1) ((%1)&0xFFFF) //ITaskbarList3 初期化 newcom iTask3, ITaskbarList3 ITaskbarList_HrInit iTask3 screen 0, ginfo_dispx, ginfo_dispy, 0, , , 640, 480 title "TabTextEditor" SetWindowLong hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_SIZEBOX | WS_MAXIMIZEBOX oncmd gosub *OnCommand, WM_COMMAND oncmd gosub *OnNotify, WM_NOTIFY oncmd gosub *OnSize, WM_SIZE onexit gosub *Exit dim MaxTab, 0 //タブの最大量 dim hEdit, 0 //エディットコントロールウィンドウハンドル dim TabIndex, 0 //タブインデックス sdim FilePath, 0 //ファイルパス MaxTab = 0 //ダミーウィンドウクラス登録 dim wce, 12 DummyWndClass = "DummyWindowClass" wce(0) = 48 wce(1) = 0 wce(2) = varptr(pDummyWndProc) wce(3) = 0 wce(4) = 0 wce(5) = hinstance wce(6) = 0 wce(7) = 0 wce(8) = 16 wce(9) = 0 wce(10)= varptr(DummyWndClass) wce(11)= 0 RegisterClassEx varptr(wce) //メニューを作成 CreatePopupMenu :hHelpMenu = stat AppendMenu hHelpMenu, MF_INSERT, IDM_HELPINDEX, "ヘルプ目次(&H)" AppendMenu hHelpMenu, MF_INSERT, IDM_ABOUT, "バージョン情報(&A)" CreatePopupMenu :hFileMenu = stat AppendMenu hFileMenu, MF_INSERT, IDM_NEW, "新規作成(&N)" AppendMenu hFileMenu, MF_INSERT, IDM_OPEN, "開く(&O)" AppendMenu hFileMenu, MF_INSERT, IDM_SAVE, "上書き保存(&S)" AppendMenu hFileMenu, MF_INSERT, IDM_SAVEAS, "名前をつけて保存(&A)" AppendMenu hFileMenu, MF_INSERT, IDM_CLOSE, "タブを閉じる(&C)" AppendMenu hFileMenu, MF_INSERT, MF_SEPARATOR, 0 AppendMenu hFileMenu, MF_INSERT, IDM_EXIT, "終了(&E)" CreateMenu :hMenu = stat AppendMenu hMenu, MF_POPUP, hFileMenu, "ファイル(&F)" AppendMenu hMenu, MF_POPUP, hHelpMenu, "ヘルプ(&H)" SetMenu hwnd, hMenu DrawMenuBar hwnd //タブを配置 CreateWindowEx 0, "systabcontrol32", "", WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN, 0, 0, ginfo_winx, ginfo_winy, hwnd, 0, hinstance, 0 hTab = stat oldTabProc = SetWindowLong(hTab, GWL_WNDPROC, varptr(pTabWndProc)) //サブクラス化 sendmsg hTab, WM_SETFONT, GetStockObject(17) doc_New "無題" stop *DummyWndProc //ダミーウィンドウのプロシージャー switch mmsg case WM_CREATE // ウィンドウの属性を変更してサムネを変更できるようにする trueValue=1 DwmSetWindowAttribute mhwnd, DWMWA_FORCE_ICONIC_REPRESENTATION, varptr(trueValue), 4 DwmSetWindowAttribute mhwnd, DWMWA_HAS_ICONIC_BITMAP, varptr(trueValue), 4 ITaskbarList3_RegisterTab iTask3, mhwnd, hwnd ITaskbarList3_SetTabOrder iTask3, mhwnd, 0 DwmInvalidateIconicBitmaps mhwnd return 0 swbreak case WM_DWMSENDICONICTHUMBNAIL //アイコンサムネイルを求めた。 SetIconicThumbnail mhwnd, hEdit(GetWindowLong(mhwnd, GWL_USERDATA)), HIWORD(mlp), LOWORD(mlp) return 0 swbreak case WM_DWMSENDICONICLIVEPREVIEWBITMAP //ライブプレビューを求めた。 dim Rect, 4 GetClientRect hTab, varptr(Rect) sendmsg hTab, TCM_ADJUSTRECT, 0, varptr(Rect) SetIconicLivePreviewBitmap mhwnd, hEdit(GetWindowLong(mhwnd, GWL_USERDATA)), Rect(0)-4, Rect(1)-1 return 0 swbreak case WM_ACTIVATE //サムネをクリックした if LOWORD(mwp)==WA_ACTIVE{ if IsIconic(hwnd):ShowWindow hwnd, SW_RESTORE doc_SetAct GetWindowLong(mhwnd, GWL_USERDATA) SetForegroundWindow hwnd return 0 } swbreak swend return DefWindowProc(mhwnd, mmsg, mwp, mlp) *TabWndProc //サブクラス化したタブコントロールのプロシージャー switch mmsg case WM_COMMAND if LOWORD(mwp)>=100{ if HIWORD(mwp)==EN_CHANGE{ //エディットコントロールの内容が変更された DwmInvalidateIconicBitmaps hDummyWnd(LOWORD(mwp)-100) //サムネを更新 return } } swbreak swend return CallWindowProc(oldTabProc, callbkarg(0), callbkarg(1), callbkarg(2), callbkarg(3)) *OnCommand if lparam==0{ //メニュー項目処理 switch LOWORD(wparam) case IDM_NEW doc_New "無題" return swbreak case IDM_OPEN dialog "txt", 16, "テキストファイル" if stat==0:return doc_Load refstr return swbreak case IDM_SAVEAS dialog "txt", 17, "テキストファイル" if stat==0:return fname = refstr if getpath(fname, 2)=="":fname+=".txt" doc_Save doc_GetAct(), fname return swbreak case IDM_SAVE if strmid(FilePath(doc_GetAct()), 0, 2)=="@:":return //新規作成ファイル doc_Save doc_GetAct(), FilePath(doc_GetAct()) return swbreak case IDM_CLOSE doc_Close doc_GetAct() return swbreak case IDM_EXIT gosub *Exit return swbreak case IDM_HELPINDEX return swbreak case IDM_ABOUT dialog "TabTextEditor ver 1.0", 0, "About" return swbreak swend } return *Exit dialog "終了しますか?", 3, "" if stat==7:return PostQuitMessage 0 return *OnNotify dupptr nmhdr, lparam, 12 if ((nmhdr(0) == hTab) && (nmhdr(2) == TCN_SELCHANGE)) { //タブが選択された tcitem = TCIF_PARAM, 0, 0, 0, 0, 0, 0 sendmsg hTab, TCM_GETCURSEL sendmsg hTab, TCM_GETITEM, stat, varptr(tcitem) doc_SetAct tcitem(6) } return *OnSize //サイズ変更を適用する MoveWindow hTab, 0, 0, ginfo_winx, ginfo_winy, 1 dim Rect, 4 GetClientRect hTab, varptr(Rect) sendmsg hTab, TCM_ADJUSTRECT, 0, varptr(Rect) MoveWindow hEdit(doc_GetAct()), Rect(0), Rect(1), Rect(2)-Rect(0), Rect(3)-Rect(1), 1 return //doc_New 新しいタブを作成 // str _fpTitle : タブのタイトル #deffunc doc_New str _fpTitle oldTabID = TabID ShowWindow hEdit(oldTabID), SW_HIDE TabID = MaxTab MaxTab++ FilePath(TabID) = "@:"+_fpTitle szText = _fpTitle tcitem = TCIF_TEXT|TCIF_PARAM, 0, 0, varptr(szText), strlen(szText), 0, TabID sendmsg hTab, TCM_GETITEMCOUNT:TabIndex(TabID) = stat sendmsg hTab, TCM_INSERTITEM, TabIndex(TabID), varptr(tcitem) sendmsg hTab, TCM_SETCURSEL, TabIndex(TabID) dim Rect, 4 GetClientRect hTab, varptr(Rect) sendmsg hTab, TCM_ADJUSTRECT, 0, varptr(Rect) CreateWindowEx WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_MULTILINE|ES_WANTRETURN, Rect(0), Rect(1), Rect(2)-Rect(0), Rect(3)-Rect(1), hTab, TabID+100, hinstance, 0 hEdit(TabID) = stat sendmsg hEdit(TabID), WM_SETFONT, GetStockObject(17) SetFocus hEdit(TabID) //ダミーウィンドウ作成(サムネイル表示に必要) CreateWindowEx WS_EX_NOACTIVATE, DummyWndClass, _fpTitle, WS_POPUP, 0, 0, 0, 0, hEdit(TabID), 0, hinstance, 0 hDummyWnd(TabID) = stat SetWindowLong hDummyWnd(TabID), GWL_USERDATA, TabID ITaskbarList_ActivateTab iTask3, hDummyWnd(TabID) ActiveTabID = TabID return 0 //doc_Load ファイルを読み込む // str _fpFilePath : ファイルパス // 成功したら1が返ります。 #deffunc doc_Load str _fpFilePath doc_New "" dirlist list, _fpFilePath, 1 if (stat == 0) : return 1 FilePath(ActiveTabID) = _fpFilePath szText = getpath(_fpFilePath, 8) tcitem = TCIF_TEXT, 0, 0, varptr(szText), strlen(szText), 0, 0 sendmsg hTab, TCM_SETITEM, TabIndex(ActiveTabID), varptr(tcitem) sendmsg hDummyWnd(ActiveTabID), WM_SETTEXT, 0, varptr(szText) sdim buf notesel buf noteload _fpFilePath noteunsel sendmsg hEdit(ActiveTabID), WM_SETTEXT, 0, varptr(buf) sdim buf,0 return 0 //doc_Save ファイルを保存 // int _fpTabID : タブID // str _fpFilePath : ファイルパス #deffunc doc_Save int _fpTabID, str _fpFilePath FilePath(_fpTabID) = _fpFilePath szText = getpath(_fpFilePath, 8) tcitem = TCIF_TEXT, 0, 0, varptr(szText), strlen(szText), 0, 0 sendmsg hTab, TCM_SETITEM, TabIndex(_fpTabID), varptr(tcitem) sendmsg hDummyWnd(ActiveTabID), WM_SETTEXT, 0, varptr(szText) sendmsg hEdit(_fpTabID), WM_GETTEXTLENGTH, 0, 0 : size = stat sdim buf, size + 2 sendmsg hEdit(_fpTabID), WM_GETTEXT, size + 2, varptr(buf) notesel buf notesave _fpFilePath noteunsel sdim buf,0 return 0 //doc_Close タブを閉じる // int _fpTabID : タブID #deffunc doc_Close int _fpTabID DestroyWindow hEdit(_fpTabID) DestroyWindow hDummyWnd(_fpTabID) hEdit(_fpTabID) = 0 hDummyWnd(_fpTabID) = 0 FilePath(_fpTabID) = "" sendmsg hTab, TCM_DELETEITEM, TabIndex(_fpTabID) TabIndex(_fpTabID) = 0 doc_SetAct 0 return //doc_GetAct() アクティブタブID取得 #defcfunc doc_GetAct return ActiveTabID //doc_SetAct アクティブタブID設定 // int _fpNewTabID : アクティブにするタブID #deffunc doc_SetAct int _fpNewTabID oldTabID = ActiveTabID ActiveTabID = _fpNewTabID sendmsg hTab, TCM_SETCURSEL, TabIndex(ActiveTabID) dim Rect, 4 GetClientRect hTab, varptr(Rect) sendmsg hTab, TCM_ADJUSTRECT, 0, varptr(Rect) ITaskbarList_ActivateTab iTask3, hDummyWnd(ActiveTabID) MoveWindow hEdit(ActiveTabID), Rect(0), Rect(1), Rect(2)-Rect(0), Rect(3)-Rect(1), 0 ShowWindow hEdit(oldTabID), SW_HIDE ShowWindow hEdit(ActiveTabID), SW_SHOW SetFocus hEdit(ActiveTabID) return 0 //サムネを設定 //SetIconicThumbnail ウィンドウハンドル, 画面コピー元ウィンドウハンドル, サムネサイズX, サムネサイズY #deffunc SetIconicThumbnail int hnd, int chnd, int sx, int sy dim Rect, 4 GetClientRect chnd, varptr(Rect) //ウィンドウキャプチャ用 32bit ビットマップ作成 dim bmi, 124/4 bmi = 40, Rect(2), Rect(3), 1|(32<<16), BI_RGB, Rect(2)*Rect(3)*4 hdc_cwnd = CreateCompatibleDC(0) hbmp_cwnd = CreateDIBSection(0, varptr(bmi), 0, varptr(lpBits), 0, 0) if (hbmp_cwnd){ hOldBmp1 = SelectObject(hdc_cwnd, hbmp_cwnd) FillRect hdc_cwnd, varptr(Rect), GetSysColorBrush(COLOR_WINDOW) sendmsg chnd, WM_PRINT, hdc_cwnd, PRF_CLIENT|PRF_CHILDREN //画面キャプチャ //サムネイル用 32bit ビットマップ作成 dim OutRect, 4 OrgRect = 0, 0, Rect(2), Rect(3) wRect=0, 0, sx, sy FitInRect OutRect, wRect, OrgRect //求められた大きさに収める thmx = OutRect(2):thmy = OutRect(3) imagesize = thmx*thmy*4 bmi = 40, thmx, thmy, 1|(32<<16),BI_RGB, imagesize hdc_thumb = CreateCompatibleDC(0) hbmp_thumb = CreateDIBSection(0, varptr(bmi), 0, varptr(lpBits), 0, 0) if (hbmp_thumb){ hOldBmp2 = SelectObject(hdc_thumb, hbmp_thumb) SetStretchBltMode hdc_thumb, HALFTONE //伸縮モード変更 hPal = CreateHalftonePalette(hdc_thumb) //ハーフトーンパレット作成 hOldPal = SelectPalette(hdc_thumb, hPal, 0) RealizePalette hdc_thumb //論理パレットを実体化 StretchBlt hdc_thumb, 0, 0, thmx, thmy, hdc_cwnd, 0, 0, Rect(2), Rect(3), SRCCOPY //伸縮コピー //あと片付け SelectPalette hdc_thumb, hOldPal, 0 DeleteObject hPal SelectObject hdc_thumb, hOldBmp2 } DeleteDC hdc_thumb SelectObject hdc_cwnd, hOldBmp1 DeleteObject hbmp_cwnd } DeleteDC hdc_cwnd DwmSetIconicThumbnail hnd, hbmp_thumb, DWM_SIT_DISPLAYFRAME //サムネイルに設定 DeleteDC hbmp_thumb return //ライブプレビューを設定 //SetIconicLivePreviewBitmap ウィンドウハンドル, 画面コピー元ウィンドウハンドル, オフセットX, オフセットY #deffunc SetIconicLivePreviewBitmap int hnd, int chnd, int sx, int sy dim Rect, 4 GetClientRect chnd, varptr(Rect) //ライブプレビュー用 32bit ビットマップ作成 imagesize = Rect(2)*Rect(3)*4 bmi = 40, Rect(2), Rect(3), 1|(32<<16),BI_RGB, imagesize hdc_livepre = CreateCompatibleDC(0) //デバイスコンテキスト作成 hbmp_livepre = CreateDIBSection(0, varptr(bmi), 0, varptr(lpBits), 0, 0) //ビットマップ作成 if (hbmp_livepre){ hOldBmp1 = SelectObject(hdc_livepre, hbmp_livepre) FillRect hdc_livepre, varptr(Rect), GetSysColorBrush(COLOR_WINDOW) sendmsg chnd, WM_PRINT, hdc_livepre, PRF_CLIENT|PRF_CHILDREN //画面キャプチャ //後片付け SelectObject hdc_livepre, hOldBmp1 } DeleteDC hdc_livepre pt = sx, sy MapWindowPoints chnd,hwnd,varptr(pt),1 DwmSetIconicLivePreviewBitmap hnd, hbmp_livepre, varptr(pt), 0 //ライブプレビュービットマップを設定 DeleteObject hbmp_livepre return #module //FitInRect 出力先(RECT構造体), 収める大きさ(RECT構造体), 元の大きさ(RECT構造体) //縦横比を保持しながら、収める大きさまで拡大縮小します。 #deffunc FitInRect array OutRect, array Rect, array OrgRect if length(Rect)!=4:return 0 if length(OrgRect)!=4:return 0 dim OutRect,4 OutRect=Rect(0),Rect(1),Rect(2),Rect(3) if (OrgRect(2)-OrgRect(0))>(OrgRect(3)-OrgRect(1)){//横のほうが長い OutRect(2)=Rect(2)//横いっぱいに OutRect(3)=int(double(OrgRect(3))*(double(Rect(2))/double(OrgRect(2)))) }else:if (OrgRect(2)-OrgRect(0))<(OrgRect(3)-OrgRect(1)){//縦のほうが長い OutRect(3)=Rect(3)//縦いっぱいに OutRect(2)=int(double(OrgRect(2))*(double(Rect(3))/double(OrgRect(3)))) } if (OutRect(2)-OutRect(0))>(Rect(2)-Rect(0)){//横のほうが長い old=OutRect(2) OutRect(2)=Rect(2)//横いっぱいに OutRect(3)=int(double(OutRect(3))*(double(Rect(2))/double(old))) }else:if (OutRect(3)-OutRect(1))>(Rect(3)-Rect(1)){//縦のほうが長い old=OutRect(3) OutRect(3)=Rect(3)//縦いっぱいに OutRect(2)=int(double(OutRect(2))*(double(Rect(3))/double(old))) } return #global
(C)2019 inonote / 無断転載禁止