Interesting WinRT code
Posted: Sat Apr 16, 2016 8:24 am
I place a copy of this here as I don't want to loose it:
http://codetter.com/?p=1091
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