LaunchFullTrustProcessForCurrentAppAsync() not work from Desktop Bridge - c++

I need launch some console app from under my packaged Win32 app using microsoft WRL. But LaunchFullTrustProcessForCurrentAppAsync not work and HRESULT = 0x80010117 in async action completed callback.
using namespace Microsoft::WRL;
using namespace ABI::Windows::ApplicationModel;
void LaunchFullTrustApp() {
ComPtr<IFullTrustProcessLauncherStatics> fullTrustProcessLauncherStatic;
auto hr = RoGetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_FullTrustProcessLauncher).Get(), __uuidof(fullTrustProcessLauncherStatic), &fullTrustProcessLauncherStatic);
CheckHr(hr);
auto onCompletedCallback = Callback<Implements<RuntimeClassFlags<ClassicCom>, IAsyncActionCompletedHandler, FtmBase>>(
[](IAsyncAction* asyncInfo, AsyncStatus asyncStatus)
{
auto hr = asyncInfo->GetResults();
CheckHr(hr); // hr = "0x80010117: Call context cannot be accessed after call completed. CallContext: [\LaunchFullTrustProcessForApp] ..."
if (asyncStatus != AsyncStatus::Completed) { // asyncStatus = Error
return S_FALSE;
}
return S_OK;
});
ComPtr<IAsyncAction> launchAction;
hr = fullTrustProcessLauncherStatic->LaunchFullTrustProcessForCurrentAppAsync(&launchAction);
CheckHr(hr);
hr = launchAction->put_Completed(onCompletedCallback.Get());
CheckHr(hr);
}
Package manifest:
...
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
...
<Extensions>
<desktop:Extension Category="windows.fullTrustProcess" Executable="HelloWorld.exe" EntryPoint="Windows.FullTrustApplication" />
</Extensions>

Related

How to host a preview handler in a dialog

I'm attempting to host a file preview handler within a dialog. I've set up an event sink for selection changes in Explorer. When the selection changes, I feed the selected shell item to the dialog, which in turn feeds it to a function that prepares the preview frame.
In general, it successfully loads the correct handler and displays the contents of the file, but for certain file types (namely, Excel and Word files), it runs into various problems like focus-loss or flashing. Here's a demo of the Excel preview handler messing up focus (and by mess up, I mean it wrongfully steals the focus from Explorer, which I'd like to maintain focus):
Word files may load successfully once, but they'll subsequently fail, especially if Word is opened.
As for the code:
For starters, here's my function for obtaining the preview handler from the file extension. This seems to work fine:
HRESULT PreviewHandlerFromExt(LPCWSTR pszExt, IPreviewHandler** ppph)
{
WCHAR szCLSID[CLSID_LEN] = { 0 };
DWORD cchOut = CLSID_LEN;
HRESULT hr = AssocQueryString( ASSOCF_INIT_DEFAULTTOSTAR,
ASSOCSTR_SHELLEXTENSION,
pszExt,
L"{8895b1c6-b41f-4c1c-a562-0d564250836f}",
szCLSID,
&cchOut );
if (FAILED(hr))
{
return hr;
}
CLSID clsid;
hr = CLSIDFromString(szCLSID, &clsid);
if (FAILED(hr))
{
return hr;
}
CComPtr<IUnknown> punk;
hr = punk.CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER);
if (FAILED(hr))
{
return hr;
}
CComPtr<IPreviewHandler> pPrevHandler;
hr = punk->QueryInterface(&pPrevHandler);
if (FAILED(hr) || !pPrevHandler)
{
return hr;
}
return pPrevHandler.CopyTo(ppph);
}
And now here's the function in my dialog that prepares the preview, given a shell item (m_pPreviewHandler is the active preview handler, IDC_PREVIEWFRAME is a placeholder in the dialog for the preview pane, and m_mapExtsToPreviewHandlers is just a map for storing preview handlers as the user comes across them):
void CMyDialog::ShowPreview(IShellItem* pShItem)
{
HRESULT hr;
if (m_pPreviewHandler)
{
m_pPreviewHandler->Unload();
m_pPreviewHandler.Release();
}
CComHeapPtr<WCHAR> pszPath;
hr = pShItem->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
if (FAILED(hr))
{
return;
}
LPWSTR pszExt = CharLower(PathFindExtension(pszPath));
auto it = m_mapExtsToPreviewHandlers.find(pszExt);
if (it == m_mapExtsToPreviewHandlers.end())
{
hr = PreviewHandlerFromExt(pszExt, &m_pPreviewHandler);
if (FAILED(hr) || !m_pPreviewHandler)
{
return;
}
m_mapExtsToPreviewHandlers[pszExt] = m_pPreviewHandler;
}
else
{
m_pPreviewHandler = m_mapExtsToPreviewHandlers[pszExt];
}
CComPtr<IInitializeWithFile> pInitWithFile;
hr = m_pPreviewHandler->QueryInterface(&pInitWithFile);
if (SUCCEEDED(hr))
{
hr = pInitWithFile->Initialize(pszPath, STGM_READ);
if (FAILED(hr))
{
return;
}
}
else
{
CComPtr<IInitializeWithStream> pInitWithStream;
hr = m_pPreviewHandler->QueryInterface(&pInitWithStream);
if (SUCCEEDED(hr))
{
CComPtr<IStream> pStream;
hr = SHCreateStreamOnFile(pszPath, STGM_READ, &pStream);
if (FAILED(hr) || !pStream)
{
return;
}
hr = pInitWithStream->Initialize(pStream, STGM_READ);
if (FAILED(hr))
{
return;
}
}
}
CWindow wndPreviewFrame( GetDlgItem(IDC_PREVIEWFRAME) );
CRect rectPreviewFrame;
wndPreviewFrame.GetClientRect(&rectPreviewFrame);
hr = m_pPreviewHandler->SetWindow(wndPreviewFrame, &rectPreviewFrame);
if (FAILED(hr))
{
return;
}
hr = m_pPreviewHandler->DoPreview();
if (FAILED(hr))
{
return;
}
hr = m_pPreviewHandler->SetRect(&rectPreviewFrame);
if (FAILED(hr))
{
return;
}
}
Does anyone know what I'm doing wrong or what might fix these focus problems?
I've also tried placing LockSetForegroundWindow at various places, but no lock.
Also, this is what the dialog resource looks like:

TaskScheduler RegisterTaskDefinition fails with NULL path in Win10

According to this MSDN doc, we may pass NULL for the path argument:
path [in]
The name of the task. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value created by the Task Scheduler service.
I have a code that use this behavior. The code works fine in Win7 and 8.1, but not in my Win10 box (ver 1709 64-bit, build 16299). In Win10, it will return 0x80070005 aka "Access Denied" when path is NULL. If I specify a name like "Foobar", it will work fine.
Test code:
// Link comsuppw.lib and taskschd.lib.
#include <stdio.h>
#include <windows.h>
#include <atlbase.h>
#include <atlstr.h>
#include <shlobj.h>
#include <taskschd.h>
#include <comutil.h>
class AutoHR {
HRESULT hr;
public:
void operator=(HRESULT hr)
{
this->hr = hr;
if (FAILED(hr)) {throw *this;}
}
HRESULT GetHR() const { return hr; }
};
static void TestTaskSched()
{
AutoHR hr;
CComPtr<ITaskService> taskSvc;
CComPtr<ITaskFolder> taskFol;
CComPtr<ITaskDefinition> taskDef;
CComPtr<IActionCollection> taskAC;
CComPtr<IAction> taskAction;
CComPtr<IExecAction> taskEA;
CComPtr<IRegisteredTask> registeredTask;
try {
hr = taskSvc.CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_ALL);
hr = taskSvc->Connect(CComVariant(),CComVariant(),CComVariant(),CComVariant());
hr = taskSvc->GetFolder(_bstr_t(L""), &taskFol);
hr = taskSvc->NewTask(0, &taskDef);
hr = taskDef->get_Actions(&taskAC);
hr = taskAC->Create(TASK_ACTION_EXEC, &taskAction);
hr = taskAction.QueryInterface<IExecAction>(&taskEA);
hr = taskEA->put_Path(_bstr_t(L"C:\\Windows\\System32\\cmd.exe"));
hr = taskEA->put_Arguments(_bstr_t(L"/k echo Testing"));
// Note that NULL is passed as the first argument.
hr = taskFol->RegisterTaskDefinition(nullptr, taskDef,
TASK_CREATE_OR_UPDATE, CComVariant(), CComVariant(),
TASK_LOGON_NONE, CComVariant(), &registeredTask);
MessageBoxW(nullptr, L"Succeeded!", L"OK", MB_ICONINFORMATION);
}
catch (AutoHR const &autohr) {
WCHAR buf[99] = {0};
wsprintfW(buf, L"HRESULT error 0x%.8X\n", autohr.GetHR());
MessageBoxW(nullptr, buf, nullptr, MB_ICONERROR);
}
}
int main()
{
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
TestTaskSched();
CoUninitialize();
}
return 0;
}
Test result:
Questions:
1) Is there a behavior change between Win10 and older Windows? I suspect there is, but I cannot find any doc that mentions it.
2) Any good alternative for this behavior? I hope I don't have to generate GUID by myself for temporary task creation.

IIS Client Certificate Mapping Authentication

I am trying to programmatically add onetoone client certificate authentication to the applicationhost.config file.
After referring to these two documents(thread1, thread2), I am sure that it is possible to implement it with different languages. And for some kind of reason I have to develop it with C++. While translating the code sample in thread1,
Below is the code snippet FYI.
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <ahadmin.h>
#include <crtdbg.h>
#include <string>
using namespace std;
void PrintPropertiesOfElement(IAppHostElement *pElement)
{
HRESULT hr = S_OK;
IAppHostPropertyCollection *pProperties = NULL;
IAppHostProperty *pProperty = NULL;
hr = pElement->get_Properties(&pProperties);
DWORD properties_count = 0;
hr = pProperties->get_Count(&properties_count);
VARIANT vtIndex;
vtIndex.vt = VT_INT;
for(DWORD i=0; i<properties_count; ++i)
{
vtIndex.intVal = i;
hr = pProperties->get_Item(vtIndex, &pProperty);
BSTR strName;
BSTR strValue;
hr = pProperty->get_Name(&strName);
hr = pProperty->get_StringValue(&strValue);
_tprintf(_T("name : %s, value: %s\n"), strName, strValue);
}
}
void PrintElementsOfCollection(IAppHostChildElementCollection *pCollection)
{
HRESULT hr = S_OK;
IAppHostElement *pElement = NULL;
DWORD elements_count = 0;
hr = pCollection->get_Count(&elements_count);
VARIANT vtIndex;
vtIndex.vt = VT_INT;
for(DWORD i=0; i<elements_count; ++i)
{
vtIndex.intVal = i;
hr = pCollection->get_Item(vtIndex, &pElement);
BSTR strName;
hr = pElement->get_Name(&strName);
_tprintf(_T("element : %s\n"), strName);
}
}
void PrintElementsOfCollection(IAppHostElementCollection *pCollection)
{
HRESULT hr = S_OK;
IAppHostElement *pElement = NULL;
DWORD elements_count = 0;
hr = pCollection->get_Count(&elements_count);
VARIANT vtIndex;
vtIndex.vt = VT_INT;
for(DWORD i=0; i<elements_count; ++i)
{
vtIndex.intVal = i;
hr = pCollection->get_Item(vtIndex, &pElement);
BSTR strName;
hr = pElement->get_Name(&strName);
_tprintf(_T("element : %s\n"), strName);
//PrintPropertiesOfElement(pElement);
}
}
struct UserCertification
{
VARIANT username;
VARIANT password;
VARIANT certification;
public:
UserCertification(wstring name, wstring pwd, wstring cert)
{
username.vt = VT_BSTR;
username.bstrVal = SysAllocString(name.c_str());
password.vt = VT_BSTR;
password.bstrVal = SysAllocString(pwd.c_str());
certification.vt = VT_BSTR;
certification.bstrVal = SysAllocString(cert.c_str());
}
};
HRESULT SetHostElementProperty(IAppHostElement *pElement, UserCertification *pUserCert)
{
HRESULT hr = S_OK;
IAppHostProperty *pProperty = NULL;
BSTR name = SysAllocString(L"userName");
BSTR password = SysAllocString(L"password");
BSTR certification = SysAllocString(L"certificate");
//name
hr = pElement->GetPropertyByName(name, &pProperty);
pProperty->put_Value(pUserCert->username);
//password
hr = pElement->GetPropertyByName(password, &pProperty);
pProperty->put_Value(pUserCert->password);
//certification
hr = pElement->GetPropertyByName(certification, &pProperty);
pProperty->put_Value(pUserCert->certification);
return hr;
}
UserCertification* GenerateUserCertification()
{
wstring username = L"jinqiu.tao#emacle.com";
wstring password = L"123456";
wstring certificate = L"xxxxxxxx";
return new UserCertification(username, password, certificate);
}
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
IAppHostWritableAdminManager * pWMgr = NULL;
IAppHostConfigManager * pCfgMgr = NULL;
IAppHostConfigFile * pCfgFile = NULL;
IAppHostConfigLocationCollection * pLocations = NULL;
IAppHostElement *pAdminSection = NULL;
IAppHostElementCollection *pElementCollection = NULL;
IAppHostChildElementCollection *pChildElements = NULL;
IAppHostElement *pElement = NULL;
IAppHostElement *pNewElement = NULL;
BSTR bstrConfigCommitPath = SysAllocString(L"MACHINE/WEBROOT/APPHOST/Default Web Site");
BSTR bstrSectionName = SysAllocString(L"system.webServer/security/authentication/iisClientCertificateMappingAuthentication");
BSTR bstrOneToOne = SysAllocString(L"oneToOneMappings");
BSTR bstrElementName = SysAllocString(L"add");
// Initialize
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
// Create
hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), NULL,
CLSCTX_INPROC_SERVER,
__uuidof( IAppHostWritableAdminManager ), (void**) &pWMgr );
pWMgr -> put_CommitPath ( bstrConfigCommitPath );
hr = pWMgr->GetAdminSection(bstrSectionName, bstrConfigCommitPath, &pAdminSection);
hr = pAdminSection->get_ChildElements(&pChildElements);
PrintElementsOfCollection(pChildElements);
hr = pAdminSection->GetElementByName(bstrOneToOne, &pElement);
hr = pElement->get_Collection(&pElementCollection);
//PrintElementsOfCollection(pElementCollection);
hr = pElementCollection->CreateNewElement(bstrElementName, &pNewElement);
//PrintPropertiesOfElement(pNewElement);
hr = SetHostElementProperty(pNewElement, GenerateUserCertification());
//got and error saying that another process is accesssing the data
hr = pElementCollection->AddElement(pNewElement); //got an error code 0x80070021 here |||||||||||||||||
PrintElementsOfCollection(pElementCollection);
// Commit the changes to the configuration system
pWMgr->CommitChanges ( );
return 0;
}
As you see, I can create a new element, but not able to add it to the element collection.
What I want to do is just add a record to the onetoonemappings part.
<location path="Default Web Site">
<system.webServer>
<security>
<access sslFlags="None" />
<authentication>
<anonymousAuthentication enabled="true" />
<iisClientCertificateMappingAuthentication enabled="true" oneToOneCertificateMappingsEnabled="true">
<oneToOneMappings>
<add userName="yonggui.yu#emacle.com" password="[enc:AesProvider:4QEVwn3c530VH5sdwCl+Sm8G2eJesNEs4SaL6U5LrXg=:enc]" certificate="MIIFOjCCBCKgAwIBAgIKOAV" />
<add userName="yuyonggui#tbp.com" password="[enc:AesProvider:iBqmPwvbefiuiUZ03AyPD/0AxzD0HIb4SlJXKQGr9Ug=:enc]" certificate="MIIEjzCCA3egAwIBAgIKGgSFpwAAAA" />
<add userName="yonggui.yu#emacle.com" password="[enc:AesProvider:DogNZMKGrLa9ih2IO9PiMNUz9Ucggu9icKD7o8+U8dQ=:enc]" certificate="MIIFZzCCBE+gAwIBAgIHGAOD3e2==" />
</oneToOneMappings>
</iisClientCertificateMappingAuthentication>
</authentication>
</security>
</system.webServer>
I hope that I have made it clear enough. If you guys need any kind of additional information, please do not hesitate to inform me.
Looking forward for your help.
Best Regards,
Jordan

Set the Default Search Engine Provider of IE with IOpenServiceManager::InstallService

I would like to set the Default Search Engine Provider of IE with IOpenServiceManager::InstallService:
Belong to the link http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_description_elements. I created the SearchProviderInfo.xml like this:
<?xml version="1.0" encoding="UTF-8"?> <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> <ShortName>Web Search</ShortName> <Description>Use Example.com to search the Web.</Description> <Tags>example web</Tags> <Contact>admin#example.com</Contact> <Url type="application/atom+xml" template="http://example.com/?q={searchTerms}&pw={startPage?}&format=atom"/> <Url type="application/rss+xml" template="http://example.com/?q={searchTerms}&pw={startPage?}&format=rss"/> <Url type="text/html" template="http://example.com/?q={searchTerms}&pw={startPage?}"/> <LongName>Example.com Web Search</LongName> <Image height="64" width="64" type="image/png">http://example.com/websearch.png</Image> <Image height="16" width="16" type="image/vnd.microsoft.icon">http://example.com/websearch.ico</Image> <Query role="example" searchTerms="cat" /> <Developer>Example.com Development Team</Developer> <Attribution> Search data Copyright 2005, Example.com, Inc., All Rights Reserved </Attribution> <SyndicationRight>open</SyndicationRight> <AdultContent>false</AdultContent> <Language>en-us</Language> <OutputEncoding>UTF-8</OutputEncoding> <InputEncoding>UTF-8</InputEncoding> </OpenSearchDescription>
Belong to the link http://msdn.microsoft.com/en-us/library/cc849088%28v=vs.85%29.aspx. I create the project "SetDefaultHelper" like this:
#include <windows.h>
#include <atlbase.h>
#include <wininet.h>
#include <urlmon.h>
#include <string>
#include "openservice.h"
#pragma comment(lib, "urlmon.lib")
void DisplayUsage()
{
wprintf(L"\r\nSetDefaultHelper.exe -- Call SetDefault API on a search provider");
wprintf(L"\r\n");
wprintf(L"\r\nUSAGE: SetDefaultHelper.exe <option>");
wprintf(L"\r\n");
wprintf(L"\r\nOptions (these are mutually exclusive!):");
wprintf(L"\r\n");
wprintf(L"\r\n /guid <guid> GUID of an installed search provider");
wprintf(L"\r\n /url <url> URL of an OpenSearch Description file");
wprintf(L"\r\n");
}
int __cdecl wmain(__in int argc, __in_ecount(argc) WCHAR* argv[])
{
HRESULT hr = E_FAIL;
BOOL fComInitialized = FALSE;
if (3 != argc)
{
DisplayUsage();
}
else if (SUCCEEDED(CoInitialize(NULL)))
{
fComInitialized = TRUE;
CComPtr<IOpenServiceManager> spManager;
hr = spManager.CoCreateInstance(CLSID_OpenServiceManager);
if (SUCCEEDED(hr))
{
CComPtr<IOpenService> spService;
if (0 == _wcsicmp(argv[1], L"/guid"))
{
// Get an IOpenService pointer from the GUID.
WCHAR szEscaped[INTERNET_MAX_URL_LENGTH] = L"";
DWORD cchEscaped = ARRAYSIZE(szEscaped);
hr = UrlEscape(argv[2], szEscaped, &cchEscaped, URL_ESCAPE_SEGMENT_ONLY);
if (SUCCEEDED(hr))
{
std::wstring wsOsid(L"x-osid:1:search:");
wsOsid += szEscaped;
hr = spManager->GetServiceByID(wsOsid.c_str(), &spService);
}
}
else if (0 == _wcsicmp(argv[1], L"/url"))
{
// Install the provider to get an IOpenService pointer.
//CComPtr<IUri> spUri;
//hr = CreateUri(argv[2], 0, 0, &spUri);
//if (SUCCEEDED(hr))
//{
hr = spManager->InstallService(argv[2], &spService);
//}
}
else
{
DisplayUsage();
hr = E_FAIL;
}
if (SUCCEEDED(hr))
{
hr = spService->SetDefault(TRUE, NULL);
}
}
}
if (fComInitialized)
{
CoUninitialize();
}
return hr;
}
I build the project ok. Both file SetDefaultHelper.exe and SearchProviderInfo.xml are same folder. In the project setting, set Configuration Properties > Debugging > Commands Arguments = /url absolutePaht/searchProvider.xml. Then run debug (F10), at line "hr = CreateUri(argv[2], 0, 0, &spUri);", the rusult hr is so stranger. I don't know why. Can you help me?
Thank you very much.
[Resolved]:
1. Don't need CreateUri //commented
2. Use a absolutely path.
Use absolute path and UrlCreateFromPath to create a file:/// like URL, pass that URL to InstallService.
Between, it seems that your XML has error.
WCHAR szURL[MAX_PATH] = L"";
DWORD cchURL = ARRAYSIZE(szURL);
hr = ::UrlCreateFromPath(argv[2], szURL, &cchURL, 0);
if (SUCCEEDED(hr))
{
hr = spManager->InstallService(argv[2], &spService);
// Now we can set it as the default.
if (SUCCEEDED(hr))
{
hr = spService->SetDefault(TRUE, NULL);
if (hr == OS_E_CANCELLED)
{
hr = E_ACCESSDENIED; // by the user!
}
}
}

Please help me check the code about Databinding in Silverlight for Windows Embedded

I'm sorry to cause you a lot of trouble to read my question, because I'm a Chinese ,my English is poor, but the question has been bothering me a long time.
When I build a test-codes about Databinding,then meet a trouble.
I creat a second thread which has a cycle to generate data-source , then the thread call a method in MainPage to populate ListBoxItem.
The method use two way to do this. One use Databinding and another use ListBoxItem's SetContent().
the result is that the Databinding run about dozens of cycles then stop,but the SetContent() can run to finish.
Following is my whole codes based Windows Embedded Silverlight Tools, and run in CEPC
MainPage.XAML
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="test6.MainPage"
Width="640" Height="480">
<Grid x:Name="LayoutRoot" Background="White">
<Button x:Name="Button1" Height="43" HorizontalAlignment="Right" Margin="0,111,83,0" VerticalAlignment="Top" Width="117" Content="Button"/>
<ListBoxItem x:Name="ListBoxItem1" HorizontalAlignment="Left" Margin="84,111,0,0" Width="138" Content="{Binding L1}" Height="52" VerticalAlignment="Top" Background="#CEFFA3A3" FontSize="16"/>
<ListBoxItem x:Name="ListBoxItem2" Height="43" HorizontalAlignment="Left" Margin="84,187,0,0" VerticalAlignment="Top" Width="138" Content="{Binding L2}" Background="#6971FF6E" FontSize="16"/>
</Grid>
First add
pWindowParameters->AllowsMultipleThreadAccess = true;
in App::GetWindowParameters , if not , SetContent() could appear like DataBinding.
Declare in MainPage.h
HRESULT MainPage::UpdateData();
and
DWORD WINAPI Thread2 (PVOID pArg);
DataValue.h:
#pragma once
#include <oleauto.h>
#include "XRCollection.h"
#include "XRPropertyBag.h"
class _declspec(uuid("{9C0158BE-D467-4284-A51A-327DEFE935C5}")) DataValue : public TPropertyBag<DataValue>
{
protected:
// Protected, create by using TPropertyBag::CreateInstance to create an instance, then call Initialize();
// this will CreateInstance will use XRObject to implement IUnknown, which saves us work.
DataValue() {};
public:
HRESULT Initialize(float l1,float l2)
{
HRESULT hr = InitializeProperties();
m_L1 =l1;
m_L2 =l2;
return hr;
}
TBoundProperty<float> m_L1;
TBoundProperty<float> m_L2;
// Mapping TBoundProperty and property names.
HRESULT InitializeProperties()
{
HRESULT hr = S_OK;
hr = BeginRegisterProperties();
if (FAILED(hr))
return hr;
hr = RegisterBoundProperty(L"L1", m_L1);
if (FAILED(hr))
return hr;
hr = RegisterBoundProperty(L"L2", m_L2);
if (FAILED(hr))
return hr;
hr = EndRegisterProperties();
return hr;
}
};
In MainPange.cpp:
#include "stdafx.h"
#include "test6Generated.h"
#include "MainPage.h"
#include "App.h"
#include "resource.h"
#include "DataValue.h"
#include "oleauto.h"
#include "XRPropertyBag.h"
static XRPtr<DataValue> pDataValue;
static XRValue xrvalueNew;
static float i=0;
// ============================================================================
// OnLoaded
//
// Description: Calls InitializeComponent to bind member variables to named
// elements, and attach event handlers specified in XAML
//
// Parameters: pRoot - The root dependency object.
// ============================================================================
HRESULT MainPage::OnLoaded(__in IXRDependencyObject* pRoot)
{
UNREFERENCED_PARAMETER(pRoot);
HRESULT hr = InitializeComponent();
// Add calls to FindName or Add___EventHandler() methods after this comment.
DataValue::CreateInstance(&pDataValue);
pDataValue->Initialize(1,2);
XRValue DataContext(pDataValue);
m_pListBoxItem1->SetDataContext(&DataContext);
//m_pListBoxItem2->SetDataContext(&DataContext);
HANDLE hThread1;
hThread1=CreateThread(NULL,0,Thread2,this,0,NULL);
CloseHandle(hThread1);
return hr;
} // OnLoaded
DWORD WINAPI Thread2 (PVOID pArg)
{
HRESULT hr = E_NOTIMPL;
MainPage* pMainPage = (MainPage *)pArg;
while(i<2000)
{
++i;
Sleep(200);
pMainPage->UpdateData();
}
return 0;
}
HRESULT MainPage::UpdateData()
{
xrvalueNew.SetValue(i);
XRAutoCriticalSection csObject;
EnterCriticalSection(&csObject);
//pItemValue->SetValue(L"ID",&xrvalueNew);
pDataValue->m_L1=i;
m_pListBoxItem2->SetContent(&xrvalueNew);
LeaveCriticalSection(&csObject);
return S_OK;
}
#pragma region GeneratedCode
// ============================================================================
// WARNING: DO NOT EDIT THIS ALWAYS-GENERATED CODE
// ============================================================================
HRESULT MainPage::InitializeComponent()
{
HRESULT hr = E_FAIL;
FindName(L"LayoutRoot", &m_pLayoutRoot);
FindName(L"Button1", &m_pButton1);
FindName(L"ListBoxItem1", &m_pListBoxItem1);
FindName(L"ListBoxItem2", &m_pListBoxItem2);
if (m_pLayoutRoot &&
m_pButton1 &&
m_pListBoxItem1 &&
m_pListBoxItem2
)
{
hr = S_OK;
}
return hr;
}
// ============================================================================
// WARNING: DO NOT EDIT THIS ALWAYS-GENERATED CODE
// ============================================================================
#pragma endregion GeneratedCode
the result like that:
http://social.msdn.microsoft.com/Forums/nl-BE/winembnatapp/thread/52e0fd82-e81b-448f-a518-1a8bef5dd8e4
What is the exact way if I want to use DataBinding?I want to build a HMI ,It maybe has hundreds of value and in per 500ms maybe refresh dozens item.
Is SetContent() a feasible way can use in a production environment?
You need to set the TPropertyBag directly. See MSDN
// Don't do this
//pDataValue->m_L1=i;
// Do this instead
pDataValue->SetValue(L"L1", &i)