Interesting WinRT code

Post Reply
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Interesting WinRT code

Post by Antonio Linares »

I place a copy of this here as I don't want to loose it:

http://codetter.com/?p=1091

Code: Select all

#include "user32.as"
#include "kernel32.as"
#include "shell32.as"
// HString
#module mHString
#uselib "msvcrt"
#func calloc "calloc" int, int
#func free "free" int
#uselib "api-ms-win-core-winrt-string-l1-1-0.dll"
#func WindowsCreateString "WindowsCreateString" wptr, int, sptr
#func WindowsDeleteString "WindowsDeleteString" wptr
// 文字列の長さ
#func WindowsGetStringLen "WindowsGetStringLen" sptr
// HSTRING_HEADERが返ってくるバージョンみたい?
#func WindowsCreateStringReference "WindowsCreateStringReference" wptr, int, sptr, sptr
#func WindowsGetStringRawBuffer "WindowsGetStringRawBuffer" sptr, sptr
#defcfunc Unicode2HString str as
/*
    sdim ws, strlen(as)*2 + 2
    cnvstow ws, as
//*/
    _as=as
    ws=""
    MultiByteToWideChar 0x00,0,varptr(_as),strlen(_as),varptr(ws),0:len=stat
    sdim ws,len*2
    MultiByteToWideChar 0x00,0,varptr(_as),strlen(_as),varptr(ws),len
    hString = 0
    WindowsCreateString varptr(ws), len, varptr(hString)
return hString
// 未使用のため
#defcfunc Unicode2HStringEx str as, var HSTRING_HEADER
    sdim ws, strlen(as)*2 + 2
    cnvstow ws, as
    hString = 0
    dim HSTRING_HEADER, 6
    WindowsCreateStringReference varptr(ws), strlen(as), varptr(HSTRING_HEADER), varptr(hString)
return hString
#deffunc DeleteHString int _hString
    WindowsDeleteString _hString
return stat
#defcfunc GetHStringLength int _hString
    WindowsGetStringLen _hString
return stat
#defcfunc HString2Unicode int _hString
    if _hString == 0 : return ""
    size = GetHStringLength(_hString) * 2
    if size <= 0 : return ""
    WindowsGetStringRawBuffer _hString, varptr(size)
    dupptr buf, stat, GetHStringLength(_hString) * 2, 2
return cnvwtos(buf)
#global
#module mCOMOBJMACRO
#define global ctype SUCCEEDED(%1) ((%1) >= 0)
#define global SafeRelease(%1) if ((varuse(%1)) && (vartype(%1) == 6)){ \
    delcom %1: \
    %1 = 0 \
}
#global
// ショートカット作成
#module mSHORTCUT
#uselib "Propsys"
#func InitPropVariantFromStringVector "InitPropVariantFromStringVector" wptr, int, sptr
#uselib "Ole32"
#func PropVariantClear "PropVariantClear" sptr
#define CLSID_ShellLink "{00021401-0000-0000-C000-000000000046}"
#define IID_IShellLink "{000214EE-0000-0000-C000-000000000046}"
#usecom IShellLink IID_IShellLink CLSID_ShellLink
#comfunc IShellLink_SetArguments 11 str
#comfunc IShellLink_SetIconLocation 17 str, int
#comfunc IShellLink_SetPath 20 str
#define IID_IPersistFile "{0000010b-0000-0000-C000-000000000046}"
#usecom IPersistFile IID_IPersistFile
#comfunc IPersistFile_Save 6 wstr, int
#define IID_IPropertyStore "{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}"
#define CLSID_PropertyStore "{e4796550-df61-448b-9193-13fc1341b163}"
#usecom IPropertyStore IID_IPropertyStore CLSID_PropertyStore
#comfunc IPropertyStore_SetValue 6 sptr, sptr
#comfunc IPropertyStore_Commit 7
#deffunc CreateShortcut str file_path, str arg, str icon_path, int icon_idx, str AppUserModelID, str out_path, \
    local pShellLink, \
    local pPropStore, \
    local wstring, \
    local wstrings, \
    local ppropvar, \
    local PKEY_AppUserModel_ID, \
    local hr
 
    hr = 0
    pShellLink = 0
    pPropStore = 0
 
    newcom pShellLink, IShellLink
    if varuse(pShellLink) == 0 : return -1
 
    IShellLink_SetPath pShellLink, file_path : hr = stat
    if SUCCEEDED(hr){
        IShellLink_SetArguments pShellLink, arg : hr = stat
        if SUCCEEDED(hr){
            IShellLink_SetIconLocation pShellLink, icon_path, icon_idx : hr = stat
            if SUCCEEDED(hr){
                querycom pPropStore, pShellLink, IPropertyStore
                if varuse(pPropStore){
                    // Unicodeに変換
                    sdim wstring, strlen(AppUserModelID) * 2 + 2
                    cnvstow wstring, AppUserModelID
                    // 配列なので(今回は1つしかないけど)
                    wstrings = varptr(wstring)
                    // PROPVARIANT 構造体
                    dim ppropvar, 4
                    // Unicode文字列→PROPVARIANT に変換
                    InitPropVariantFromStringVector varptr(wstrings), 1/*今回は1つだけなので*/, varptr(ppropvar) : hr = stat
                    if SUCCEEDED(hr){
                        PKEY_AppUserModel_ID = 0x9F4C2855, 0x4B399F79, 0xD4E1D0A8, 0xF3D5E12D, 5
                        IPropertyStore_SetValue pPropStore, varptr(PKEY_AppUserModel_ID), varptr(ppropvar) : hr = stat
                        if SUCCEEDED(hr){
                            IPropertyStore_Commit pPropStore : hr = stat
                            if SUCCEEDED(hr){
                                IPersistFile_Save pShellLink, out_path, 1 : hr = stat
                            }
                        }
                        PropVariantClear varptr(ppropvar)
                    }
                }
            }
        }
    }
    // SafeRelease
    SafeRelease pPropStore
    SafeRelease pShellLink
return hr
#global
// AppUserModel_IDを設定(任意のタイミングで変更可能)
#module mAPPIDS
#uselib "shell32"
#func SHGetPropertyStoreForWindow "SHGetPropertyStoreForWindow" sptr, sptr, sptr
#func GetCurrentProcessExplicitAppUserModelID "GetCurrentProcessExplicitAppUserModelID" wptr
#func SetCurrentProcessExplicitAppUserModelID "SetCurrentProcessExplicitAppUserModelID" wstr
#uselib "Propsys"
#func InitPropVariantFromString "InitPropVariantFromString" wstr, sptr
#func InitPropVariantFromStringVector "InitPropVariantFromStringVector" wptr, int, sptr
#func PropVariantToStringAlloc "PropVariantToStringAlloc" sptr, wptr
#uselib "Ole32"
#func PropVariantClear "PropVariantClear" sptr
#define IID_IPropertyStore "{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}"
#define CLSID_PropertyStore "{e4796550-df61-448b-9193-13fc1341b163}"
#usecom IPropertyStore IID_IPropertyStore CLSID_PropertyStore
#comfunc IPropertyStore_SetValue 6 sptr, sptr
#comfunc IPropertyStore_Commit 7
#deffunc SetAppUserModelID int _hwnd, str AppUserModelID, \
    local propStorePtr, \
    local IID_IPropertyStore_Array, \
    local pPropStore, \
    local wstring, \
    local wstrings, \
    local ppropvar, \
    local hr
 
    hr = 0
    pPropStore = 0
    propStorePtr = 0
    IID_IPropertyStore_Array = 0x886d8eeb, 0x44468cf2, 0xbacd028d, 0x99cfbd1d
    PKEY_AppUserModel_ID = 0x9F4C2855, 0x4B399F79, 0xD4E1D0A8, 0xF3D5E12D, 5
 
    SHGetPropertyStoreForWindow _hwnd, varptr(IID_IPropertyStore_Array), varptr(propStorePtr)
    if stat == 0 && propStorePtr != 0{
        newcom pPropStore, IPropertyStore, -1, propStorePtr
        if varuse(pPropStore){
            // Win7 では廃止されているらしい
            // propsys.dll 7.0
            /*
            mes varptr(InitPropVariantFromString)
            InitPropVariantFromString "net.hinekure.test.hsp3", varptr(ppropvar)
            */
 
            // Unicodeに変換
            sdim wstring, strlen(AppUserModelID) * 2 + 2
            cnvstow wstring, AppUserModelID
            // 配列なので(今回は1つしかないけど)
            wstrings = varptr(wstring)
 
            // PROPVARIANT 構造体
            dim ppropvar, 4
            // Unicode文字列→PROPVARIANT に変換
            InitPropVariantFromStringVector varptr(wstrings), 1, varptr(ppropvar) : hr = stat
            if SUCCEEDED(hr){
                IPropertyStore_SetValue pPropStore, varptr(PKEY_AppUserModel_ID), varptr(ppropvar) : hr = stat
                if SUCCEEDED(hr){
                    IPropertyStore_Commit pPropStore : hr = stat
                }
                PropVariantClear varptr(ppropvar)
            }
        }
    }
 
    // SafeRelease
    SafeRelease pPropStore
 
return hr
#global
#module mToast
#uselib "Combase.dll"
#func RoGetActivationFactory "RoGetActivationFactory" sptr, sptr, sptr
#func RoActivateInstance "RoActivateInstance" sptr, sptr
#func RoInitialize "RoInitialize" int
#func RoUninitialize "RoUninitialize"
 
#define IID_IToastNotificationManagerStatics "{50ac103f-d235-4598-bbef-98fe4d1a3ad4}"
#define CLSID_ToastNotificationManagerStatics "{6db7cd52-e3b7-4ecc-bb1f-388aeef6bb50}"
#usecom IToastNotificationManagerStatics IID_IToastNotificationManagerStatics CLSID_ToastNotificationManagerStatics
// WinRT は0~5まで使ってる
#comfunc IToastNotificationManagerStatics_CreateToastNotifier 6 sptr
#comfunc IToastNotificationManagerStatics_CreateToastNotifierWithId 7 sptr, sptr
#comfunc IToastNotificationManagerStatics_GetTemplateContent 8 int, sptr
 
;#define CLSID_XMLDocument "{CFC399AF-D876-11d0-9C10-00C04FC99C8E}"
;#define IID_IXMLDocument "{F52E2B61-18A1-11d1-B105-00805F49916B}"
#define CLSID_XMLDocument "{AF75D6AD-E307-4052-8CB1-BF2052E734F0}"
#define IID_IXMLDocument "{F7F3A506-1E87-42D6-BCFB-B8C809FA5494}"
#usecom IXMLDocument IID_IXMLDocument CLSID_XMLDocument
// WinRT は0~5まで使ってる
#comfunc IXMLDocument_CreateTextNode 11 sptr, sptr
#comfunc IXMLDocument_GetElementsByTagName 16 sptr, sptr
 
#define CLSID_XmlNodeList "{AF75D6AD-E307-4052-8CB1-BF2052E734F0}"
#define IID_IXmlNodeList "{8C60AD77-83A4-4EC1-9C54-7BA429E13DA6}"
#usecom IXmlNodeList IID_IXmlNodeList CLSID_XmlNodeList
// WinRT は0~5まで使ってる
#comfunc IXmlNodeList_get_Length 6 sptr
#comfunc IXmlNodeList_Item 7 int, sptr
 
#define CLSID_XmlNode "{AF75D6AD-E307-4052-8CB1-BF2052E734F0}"
#define IID_IXmlNode "{1C741D59-2122-47D5-A856-83F3D4214875}"
#usecom IXmlNode IID_IXmlNode CLSID_XmlNode
#comfunc IXmlNode_get_NodeValue 6 sptr
#comfunc IXmlNode_get_NodeType 8 sptr
#comfunc IXmlNode_AppendChild 22 sptr, sptr
 
#define CLSID_XmlText "{AF75D6AD-E307-4052-8CB1-BF2052E734F0}"
#define IID_IXmlText "{F931A4CB-308D-4760-A1D5-43B67450AC7E}"
#usecom IXmlText IID_IXmlText CLSID_XmlText
#comfunc IXmlText_QueryInterface 0 sptr, sptr
 
// IToastNotificationManager のことらしい
#define IID_IToastNotifier "{75927B93-03F3-41EC-91D3-6E5BAC1B38E7}"
#define CLSID_ToastNotifier "{6db7cd52-e3b7-4ecc-bb1f-388aeef6bb50}"
#usecom IToastNotifier IID_IToastNotifier CLSID_ToastNotifier
#comfunc IToastNotifier_Show 6 sptr
#comfunc IToastNotifier_Hide 7 sptr
 
#define IID_IToastNotificationFactory "{04124B20-82C6-4229-B109-FD9ED4662B53}"
#define CLSID_ToastNotificationFactory "{6db7cd52-e3b7-4ecc-bb1f-388aeef6bb50}"
#usecom IToastNotificationFactory IID_IToastNotificationFactory CLSID_ToastNotificationFactory
#comfunc IToastNotificationFactory_CreateToastNotification 6 sptr, sptr
 
#define IID_IToastNotification "{997E2675-059E-4E60-8B06-1760917C8B80}"
#define CLSID_ToastNotification "{6db7cd52-e3b7-4ecc-bb1f-388aeef6bb50}"
#usecom IToastNotification IID_IToastNotification CLSID_ToastNotification
 
#define IID_IXmlNodeSerializer "{5CC5B382-E6DD-4991-ABEF-06D8D2E7BD0C}"
#define CLSID_XmlNodeSerializer "{AF75D6AD-E307-4052-8CB1-BF2052E734F0}"
#usecom IXmlNodeSerializer IID_IXmlNodeSerializer CLSID_XmlNodeSerializer
#comfunc IXmlNodeSerializer_GetXml 6 sptr
#comfunc IXmlNodeSerializer_get_InnerText 7 sptr
#comfunc IXmlNodeSerializer_put_InnerText 8 sptr
 
#deffunc WinRTAPIInit
    RoInitialize 1
return stat
#deffunc WinRTAPIUnInit
    RoUninitialize
return stat
#deffunc CreateToastXml var _pTnms_, int _Template, var _pXml_, \
    local inputXmlPtr, \
    local _pTnms, \
    local hr
 
    _pXml = _pXml_
    _pTnms = _pTnms_
    inputXmlPtr = 0
    // ToastTemplateType_ToastText01 = 4
    IToastNotificationManagerStatics_GetTemplateContent _pTnms, _Template/*4*/, varptr(inputXmlPtr) : hr = stat
    if SUCCEEDED(hr){
        newcom _pXml, IXMLDocument, -1, inputXmlPtr
        if varuse(_pXml){
            hr = 0
        }else{
            hr = -1
        }
        _pXml_ = _pXml
    }
    /*
    querycom pXns, _pXml_, IXmlNodeSerializer
    hString_test = 0
    IXmlNodeSerializer_GetXml pXns, varptr(hString_test)
    dialog strf("0x%08x, %d", stat, stat)
    dialog HString2Unicode(hString_test)
    */
return hr
#deffunc SetImageSrc str _ImagePath, var _pXml2_
    if _ImagePath == "" : return 0
return
#deffunc SetTextValues array Text, var _pXml_, \
    local num, \
    local nodeListPtr, \
    local hString2, \
    local pNodeList, \
    local nodeListLength, \
    local hString3, \
    local textNodePtr, \
    local pTextNode, \
    local pInputText, \
    local AppendedChildPtr, \
    local inputTextPtr, \
    local pTmp, \
    local hr
 
    pNodeList = 0
    nodeListPtr = 0
    hString2 = Unicode2HString("text")
 
    IXMLDocument_GetElementsByTagName _pXml_, hString2, varptr(nodeListPtr) : hr = stat
    if SUCCEEDED(hr){
        newcom pNodeList, IXmlNodeList, -1, nodeListPtr
        if varuse(pNodeList){
            nodeListLength = 0
            IXmlNodeList_get_Length pNodeList, varptr(nodeListLength) : hr = stat
            if SUCCEEDED(hr){
                // 短いほうを選ぶ
                if nodeListLength < length(Text){
                    num = nodeListLength
                }else{
                    num = length(Text)
                }
                repeat limit(num, 1, 3)
                    hString3 = Unicode2HString(Text(cnt))
                    ;dialog HString2Unicode(hString3)
                    textNodePtr = 0
                    IXmlNodeList_Item pNodeList, cnt, varptr(textNodePtr) : hr = stat
                    if SUCCEEDED(hr){
                        newcom pTextNode, IXmlNode, -1, textNodePtr
                        if varuse(pTextNode){
                            inputTextPtr = 0
                            IXMLDocument_CreateTextNode _pXml_, hString3, varptr(inputTextPtr) : hr = stat
                            if SUCCEEDED(hr){
                                newcom pInputText, IXmlText, -1, inputTextPtr
                                if varuse(pInputText){
                                    AppendedChildPtr = 0
                                    // varptrじゃなくてlpeekでcomポインタ取得 → やめた
                                    IXmlNode_AppendChild pTextNode, inputTextPtr/*lpeek(pInputText, 0)*/, varptr(AppendedChildPtr) : hr = stat
                                    if SUCCEEDED(hr){
                                        newcom pTmp, IXmlNode, -1, AppendedChildPtr
 
                                        ;querycom pXns2, pTmp, IXmlNodeSerializer
 
                                        // innerTextで日本語が挿入できない
                                        ;hString6 = Unicode2HString("test") // ←これはOK
                                        ;hString6 = Unicode2HString("testだよ!")
                                        ;IXmlNodeSerializer_put_InnerText pXns2, hString6
                                        ;dialog strf("0x%08x, %d", stat, stat)
 
                                        // 挿入したのを見てみる
                                        ;hString_test = 0
                                        ;IXmlNodeSerializer_get_InnerText pXns2, varptr(hString_test)
                                        ;dialog strf("0x%08x, %d", stat, stat)
                                        ;dialog "Debug:"+HString2Unicode(hString_test)
 
                                        SafeRelease pTmp
                                    }
                                }
                            }
                        }
                    }
                    SafeRelease pInputText
                    SafeRelease pTextNode
                    DeleteHString hString3
                loop
            }
        }
    }
 
    //
    SafeRelease pNodeList
    DeleteHString hString2
 
    // みてみる?
    /*
    querycom pXns, _pXml_, IXmlNodeSerializer
    hString_test = 0
    IXmlNodeSerializer_GetXml pXns, varptr(hString_test)
    dialog strf("0x%08x, %d,\n %s", stat, stat, HString2Unicode(hString_test))
    */
 
return hr
#deffunc ShowToast array _Text, str _ImagePath, int Template, str AppUserModelID, \
    local pTnms, \
    local hString, \
    local hString4, \
    local guid, \
    local toastStaticsPtr, \
    local hString_APPsID, \
    local pXml, \
    local notifierPtr, \
    local pNotifier, \
    local factoryPtr, \
    local pFactory, \
    local toastPtr, \
    local pToast, \
    local hr
 
    pTnms = 0
    pXml = 0
    pNotifier = 0
    pFactory = 0
    pToast = 0
 
    // Unicode文字列からHStringに変換するみたいよ
    hString = Unicode2HString("Windows.UI.Notifications.ToastNotificationManager")
    hString4 = Unicode2HString("Windows.UI.Notifications.ToastNotification")
    hString_APPsID = Unicode2HString(AppUserModelID)
 
    // IToastNotificationManagerStatics
    guid = 0x50ac103f, 0x4598d235, 0xfe98efbb, 0xd43a1a4d
    toastStaticsPtr = 0
    RoGetActivationFactory hString, varptr(guid), varptr(toastStaticsPtr) : hr = stat
    ;dialog HString2Unicode(hString)
    if hr == 0 && toastStaticsPtr != 0{
        newcom pTnms, IToastNotificationManagerStatics, -1, toastStaticsPtr
        CreateToastXml pTnms, Template, pXml : hr = stat
        if SUCCEEDED(hr){
            SetTextValues _Text, pXml : hr = stat
            if SUCCEEDED(hr){
                // 未実装
                SetImageSrc _ImagePath, pXml : hr = stat
                if SUCCEEDED(hr){
                    notifierPtr = 0
                    IToastNotificationManagerStatics_CreateToastNotifierWithId pTnms, hString_APPsID, varptr(notifierPtr) : hr = stat
                    if SUCCEEDED(hr){
                        newcom pNotifier, IToastNotifier, -1, notifierPtr
                        if varuse(pNotifier){
                            factoryPtr = 0
                            // IToastNotificationFactory
                            guid = 0x04124B20, 0x422982C6, 0x9EFD09B1, 0x532B66D4
                            RoGetActivationFactory hString4, varptr(guid), varptr(factoryPtr) : hr = stat
                            if hr == 0 && factoryPtr != 0{
                                newcom pFactory, IToastNotificationFactory, -1, factoryPtr
                                if varuse(pFactory){
                                    toastPtr = 0
                                    IToastNotificationFactory_CreateToastNotification pFactory, lpeek(pXml, 0), varptr(toastPtr) : hr = stat
                                    if SUCCEEDED(hr){
                                        newcom pToast, IToastNotification, -1, toastPtr
                                        if varuse(pToast){
                                            IToastNotifier_Show pNotifier, toastPtr
                                            if SUCCEEDED(hr){
 
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
 
    SafeRelease pToast
    SafeRelease pFactory
    SafeRelease pNotifier
    SafeRelease pXml
    SafeRelease pTnms
 
    DeleteHString hString_APPsID
    DeleteHString hString4
    DeleteHString hString
return hr
#global
#enum ToastTemplateType_ToastImageAndText01 = 0
#enum ToastTemplateType_ToastImageAndText02
#enum ToastTemplateType_ToastImageAndText03
#enum ToastTemplateType_ToastImageAndText04
#enum ToastTemplateType_ToastText01
#enum ToastTemplateType_ToastText02
#enum ToastTemplateType_ToastText03
#enum ToastTemplateType_ToastText04
 
    // Win8 のトースト通知を使用するには、アプリ一覧に
    // AppUserModelIDを設定したショートカットを配置する必要がある
 
    // 初期化するのん
    WinRTAPIInit
 
    // 適当なAppUserModelIDを指定する
    // CompanyName.ProductName.SubProduct.VersionInformation な形式が良い
    // http://msdn.microsoft.com/ja-jp/library/windows/apps/dd378459.aspx
    AppUserModelID = "net.hinekure.hsp.test"
 
    // 現在の実行ファイルのパス名
    sdim exepath, 1024 + 1
    GetModuleFileNameA 0, varptr(exepath), 1024
 
    // ショートカット作成先のパス名(?:\Users\xxx\AppData\Roaming\)
    lnkpath = dirinfo($1001A) + "\\Microsoft\\Windows\\Start Menu\\Programs\\"+"HSP3Test.lnk"
 
    // ショートカット作成(アプリ一覧に)
    CreateShortcut exepath, "", exepath, 0, AppUserModelID, lnkpath
    mes stat
 
    // 現在のウィンドウに 指定したAppUserModelID を設定する
    SetAppUserModelID hwnd, AppUserModelID
    mes stat
 
    text = "日本語の", "通知", "試験!!!!"
 
    // トースト通知してみる
 
    // 第1引数は、表示したい文字列を最大3つまでの配列変数で指定
    // 3つ使えるのは、
    // ToastTemplateType_ToastImageAndText04
    // ToastTemplateType_ToastText04
    // です。
    // 第2引数は、画像パスを指定(ただし未実装)
    // 第3引数は、テンプレートIDを指定
    // 第4引数は、AppUserModelIDを指定
    ShowToast text, "", ToastTemplateType_ToastText04, AppUserModelID
    mes strf("0x%08x, %d", stat, stat)
 
    // 終了時にでも実行
    WinRTAPIUnInit
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply