**CopyResource is not woorking,everyone knows why?i have setted GetSharedHandle and OpenSharedResource.
//desc1
m_desc.Width = rendererInfo.SrcBounds.Width;
m_desc.Height = rendererInfo.SrcBounds.Height;
m_desc.Format = rendererInfo.SrcFormat;
m_desc.ArraySize = 1;
m_desc.BindFlags = 0;
m_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
m_desc.SampleDesc.Count = 1;
m_desc.SampleDesc.Quality = 0;
m_desc.MipLevels = 1;
m_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
m_desc.Usage = D3D11_USAGE_STAGING;
m_destdesc = m_desc;
//desc2
m_destdesc.Usage = D3D11_USAGE_DEFAULT;
m_destdesc.CPUAccessFlags = 0;
...
IDXGIResource* copyResource = nullptr;
hr = m_copyTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)©Resource);
if (FAILED(hr))
return false;
HANDLE shareHandle = nullptr;
hr = copyResource->GetSharedHandle(&shareHandle);
copyResource->Release();
copyResource = nullptr;
ID3D11Resource* tempResource = nullptr;
ID3D11Texture2D* tempTex2D = nullptr;
hr = m_device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource), (void**)(&tempResource));
tempResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&tempTex2D));
ID3D11Device* ppDevice = nullptr;
tempTex2D->GetDevice(&ppDevice);
tempResource->Release();
//DirectX::SaveWICTextureToFile(m_deviceContext, tempTex2D, GUID_ContainerFormatJpeg, L"d:/glinterop2.jpg");
ID3D11DeviceContext* tempContext = nullptr;
ppDevice->GetImmediateContext(&tempContext);
tempContext->CopyResource(m_destTexture2D, tempTex2D);
tempContext->Flush();
ID3D11DeviceContext* destContext = nullptr;
pContext->getCurrentD3D11Device()->GetImmediateContext(&destContext);
DirectX::SaveWICTextureToFile(destContext, m_destTexture2D, GUID_ContainerFormatJpeg, L"d:/glinterop3.jpg");
//destContext->Release();
//tempTex2D->Release();
if (m_deskDupl) {
hr = m_deskDupl->ReleaseFrame();
}**
IDXGIResource* copyResource = nullptr;
hr = m_destTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)©Resource);
if (FAILED(hr))
return false;
HANDLE shareHandle = nullptr;
hr = copyResource->GetSharedHandle(&shareHandle);
copyResource->Release();
copyResource = nullptr;
ID3D11Texture2D* tempTex2D = nullptr;
hr = m_device->OpenSharedResource(shareHandle, __uuidof(ID3D11Texture2D), (void**)(&tempTex2D));
m_deviceContext->CopyResource(tempTex2D, m_copyTexture2D);
m_deviceContext->Flush();
ID3D11Device* ppDevice = nullptr;
tempTex2D->GetDevice(&ppDevice);
ID3D11DeviceContext* tempContext = nullptr;
ppDevice->GetImmediateContext(&tempContext);
DirectX::SaveWICTextureToFile(tempContext, tempTex2D, GUID_ContainerFormatJpeg, L"d:/glinterop2.jpg");
tempTex2D->Release();
tempTex2D = nullptr;
tempContext->Release();
tempContext = nullptr;
ppDevice->Release();
ppDevice = nullptr;
DirectX::SaveWICTextureToFile(m_destContext, m_destTexture2D, GUID_ContainerFormatJpeg, L"d:/glinterop3.jpg");
if (m_deskDupl) {
hr = m_deskDupl->ReleaseFrame();
}
Related
I use dxgi to capture window, since the windows maybe resized, so I use IDXGISwapChain1 and recreate framepool, but now I can't get the surface since GetRestrictToOutput always return null.
void OnFrameArrived(winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool const &sender,winrt::Windows::Foundation::IInspectable const &)
{
const winrt::Windows::Graphics::Capture::Direct3D11CaptureFrame frame = sender.TryGetNextFrame();
auto swapChainResizedToFrame = TryResizeSwapChain(frame);
winrt::com_ptr<ID3D11Texture2D> backBuffer;
winrt::check_hresult(m_swapChain->GetBuffer(0, winrt::guid_of<ID3D11Texture2D>(), backBuffer.put_void()));
winrt::com_ptr<ID3D11Texture2D> frameSurface = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
m_d3dContext->CopyResource(backBuffer.get(), frameSurface.get());
DXGI_PRESENT_PARAMETERS presentParameters{};
m_swapChain->Present1(1, 0, &presentParameters);
//winrt::com_ptr<IDXGIOutput> dxgiOutput = nullptr;
IDXGIOutput* dxgiOutput = nullptr;
BOOL full;
m_swapChain->GetRestrictToOutput(&dxgiOutput);
if(dxgiOutput!=nullptr){
std::cerr <<"33333333333333"<<std::endl;
...
}
m_framePool.Recreate(m_device, m_pixelFormat, 2, m_lastSize);
If I use getbuffer to get the image data, if the window size is changed, then the image is black, the code is as below:
winrt::com_ptr<ID3D11Texture2D> renderBuffer;
winrt::check_hresult(m_swapChain->GetBuffer(0, winrt::guid_of<ID3D11Texture2D>(), renderBuffer.put_void()));
if(renderBuffer != nullptr){
D3D11_TEXTURE2D_DESC desc;
renderBuffer->GetDesc(&desc);
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
winrt::com_ptr<ID3D11Texture2D> textureCopy;
auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);
winrt::check_hresult(d3dDevice->CreateTexture2D(&desc, nullptr, textureCopy.put()));
m_d3dContext->CopyResource(textureCopy.get(), renderBuffer.get());
winrt::com_ptr<IDXGISurface> dxgi_surface = nullptr;
HRESULT hr = textureCopy->QueryInterface(__uuidof(IDXGISurface), (void **)(&dxgi_surface));
DXGI_MAPPED_RECT mapped_rect;
hr = dxgi_surface->Map(&mapped_rect, DXGI_MAP_READ);
unsigned int imgSize = desc.Width * desc.Height * 4;
uint8_t* buffer = new uint8_t[imgSize];
int dst_rowpitch = desc.Width * 4;
for (unsigned int h = 0; h < desc.Height; h++) {
memcpy_s(buffer + h * dst_rowpitch, dst_rowpitch, (BYTE*)mapped_rect.pBits + h * mapped_rect.Pitch, min(mapped_rect.Pitch, dst_rowpitch));
}
dxgi_surface->Unmap();
I am trying to implement a local login from my custom Credentials Provider. For that, I try to use the MSV1_0 authentication package, but it keeps failing, yielding an INVALID_PARAMETER status.
The code seems like that:
static void _UnicodeStringPackedUnicodeStringCopy(
const UNICODE_STRING& rus,
PWSTR pwzBuffer,
UNICODE_STRING* pus
) {
pus->Length = rus.Length;
pus->MaximumLength = rus.Length;
pus->Buffer = pwzBuffer;
CopyMemory(pus->Buffer, rus.Buffer, pus->Length);
}
HRESULT LsaInitStringW(PUNICODE_STRING pszDestinationString, PCWSTR pszSourceString)
{
size_t cchLength;
HRESULT hr = StringCchLengthW(pszSourceString, USHORT_MAX, &cchLength);
if (SUCCEEDED(hr))
{
USHORT usLength;
hr = SizeTToUShort(cchLength, &usLength);
if (SUCCEEDED(hr))
{
pszDestinationString->Buffer = (PWCHAR)pszSourceString;
pszDestinationString->Length = usLength * sizeof(WCHAR);
pszDestinationString->MaximumLength = pszDestinationString->Length + 1;
hr = S_OK;
}
}
return hr;
}
HRESULT MsvLogonPack(
const MSV1_0_INTERACTIVE_LOGON& milIn,
BYTE** prgb,
DWORD* pcb
) {
size_t cb = sizeof(milIn)
+ milIn.LogonDomainName.Length
+ milIn.UserName.Length
+ milIn.Password.Length;
MSV1_0_INTERACTIVE_LOGON* milOut = (MSV1_0_INTERACTIVE_LOGON*)CoTaskMemAlloc(cb);
if (!milOut) {
return E_OUTOFMEMORY;
}
milOut->MessageType = milIn.MessageType;
BYTE *pbBuffer = (BYTE*)milOut + sizeof(*milOut);
_UnicodeStringPackedUnicodeStringCopy(milIn.LogonDomainName, (PWSTR)pbBuffer, &milOut->LogonDomainName);
pbBuffer += milOut->LogonDomainName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.UserName, (PWSTR)pbBuffer, &milOut->UserName);
pbBuffer += milOut->UserName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.Password, (PWSTR)pbBuffer, &milOut->Password);
pbBuffer += milOut->Password.Length;
if (pbBuffer != (BYTE*)milOut + cb) {
return E_ABORT;
}
*prgb = (BYTE*)milOut;
*pcb = cb;
return S_OK;
}
HRESULT GetMsvPackage(ULONG * pulAuthPackage) {
HRESULT hr;
HANDLE hLsa;
NTSTATUS status = LsaConnectUntrusted(&hLsa);
if (SUCCEEDED(HRESULT_FROM_NT(status))) {
ULONG ulAuthPackage;
LSA_STRING lsaszKerberosName;
LsaInitString(&lsaszKerberosName, MSV1_0_PACKAGE_NAME);
status = LsaLookupAuthenticationPackage(hLsa, &lsaszKerberosName, &ulAuthPackage);
if (SUCCEEDED(HRESULT_FROM_NT(status))) {
*pulAuthPackage = ulAuthPackage;
hr = S_OK;
}
else {
hr = HRESULT_FROM_NT(status);
}
LsaDeregisterLogonProcess(hLsa);
}
else {
hr = HRESULT_FROM_NT(status);
}
return hr;
}
HRESULT MyCredential::CompleteAuthentication(CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs,
PWSTR* ppwszOptionalStatusText,
CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon) {
HRESULT hr;
pcpcs->clsidCredentialProvider = CLSID_MyProvider;
MSV1_0_INTERACTIVE_LOGON mil;
mil.MessageType = MsV1_0WorkstationUnlockLogon;
hr = LsaInitStringW(&mil.LogonDomainName, L"");
if (SUCCEEDED(hr)) hr = LsaInitStringW(&mil.UserName, L"tester");
if (SUCCEEDED(hr)) hr = LsaInitStringW(&mil.Password, L"12345");
if (SUCCEEDED(hr)) {
hr = MsvLogonPack(mil, &pcpcs->rgbSerialization, &pcpcs->cbSerialization);
if (SUCCEEDED(hr)) {
ULONG ulAuthPackage;
hr = GetMsvPackage(&ulAuthPackage);
if (SUCCEEDED(hr)) {
pcpcs->ulAuthenticationPackage = ulAuthPackage;
}
}
}
return hr;
}
This keeps giving a status of INVALID_PARAMETER, with sub-status 0. I tried replacing the MsV1_0InteractiveLogon with MsV1_0WorkstationUnlockLogon, which got me a status of STATUS_LOGON_FAILURE with sub-status INTERNAL_ERROR.
What would be suggested to solve this issue?
After some research and trial, I figured out the problem. The issue was in the Unicode Strings being absolute, while they are required to be relative to the start of the structure. So I made them relative:
_UnicodeStringPackedUnicodeStringCopy(milIn.LogonDomainName, (PWSTR)pbBuffer, &milOut->LogonDomainName);
milOut->LogonDomainName.Buffer = (PWSTR)(pbBuffer - (BYTE*)milOut);
pbBuffer += milOut->LogonDomainName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.UserName, (PWSTR)pbBuffer, &milOut->UserName);
milOut->UserName.Buffer = (PWSTR)(pbBuffer - (BYTE*)milOut);
pbBuffer += milOut->UserName.Length;
_UnicodeStringPackedUnicodeStringCopy(milIn.Password, (PWSTR)pbBuffer, &milOut->Password);
milOut->Password.Buffer = (PWSTR)(pbBuffer - (BYTE*)milOut);
pbBuffer += milOut->Password.Length;
This behavior is documented for KERB_CERTIFICATE_LOGON structure, but not for MSV1_0_INTERACTIVE_LOGON, for some reason.
I'm try to communicate with \Windows\SbApiPort port .
The problem is that I get an error from NtRequestPort (0xc000000d - status invalid parameter).
The parameters of PORT_MESSAGE are not documented so I don't know where is my problem...
I tried to change the length, CallbackId, but the same problem...
Thanks for the help !
Here is the code:
HANDLE hSection=0;
LARGE_INTEGER SecSize;
SecSize.LowPart=0x10000;
SecSize.HighPart=0x0;
if(NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &SecSize, PAGE_READWRITE,SEC_COMMIT ,NULL))
{
printf("couldn't create a section");
}
HANDLE hPort;
PORT_VIEW sectionInfo;
REMOTE_PORT_VIEW mapInfo;
byte ConnectDataBuffer[0x100];
DWORD Size = sizeof(ConnectDataBuffer);
UNICODE_STRING uStr;
WCHAR * uString=L"\\Windows\\SbApiPort";
DWORD maxSize;
SECURITY_QUALITY_OF_SERVICE qos;
for (int i=0 ; i < 0x100 ; i++)
{
ConnectDataBuffer[i]=0xcc;
}
memset(§ionInfo, 0, sizeof(sectionInfo));
memset(&mapInfo, 0, sizeof(mapInfo));
memset(&mapInfo, 0, sizeof(mapInfo));
memset(&qos, 0, sizeof(qos));
qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
qos.ImpersonationLevel = SecurityImpersonation;
qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
qos.EffectiveOnly = TRUE;
sectionInfo.Length = sizeof(LPC_SECTION_OWNER_MEMORY);
sectionInfo.SectionHandle = hSection;
sectionInfo.SectionOffset = 0;
sectionInfo.ViewSize = 0x10000;
sectionInfo.ViewBase = NULL;
sectionInfo.ViewRemoteBase = NULL;
mapInfo.Length = sizeof(LPC_SECTION_MEMORY);
mapInfo.ViewSize = 0;
mapInfo.ViewBase = NULL;
uStr.Length = wcslen(uString)*2;
uStr.MaximumLength = wcslen(uString)*2+2;
uStr.Buffer =uString;
NTSTATUS res = NtConnectPort(&hPort,&uStr,&qos,§ionInfo,&mapInfo,&maxSize,(DWORD*)&ConnectDataBuffer,&Size);
if (res)
{
printf("Could not connect to LPC port.\n -%x", res);
return 1;
}
PORT_MESSAGE PortMessage;
ZeroMemory(&PortMessage,sizeof(PORT_MESSAGE));
PortMessage.u1.Length = 0x20;
PortMessage.u2.s2.DataInfoOffset = 15;
PortMessage.u2.ZeroInit = 0x20;
PortMessage.MessageId = LPC_REQUEST;
PortMessage.ClientViewSize = 0x20;
PortMessage.ClientId.UniqueProcess = GetCurrentProcess();
PortMessage.ClientId.UniqueThread = GetCurrentThread();
PortMessage.CallbackId = 0;
res = NtRequestPort(hPort, &PortMessage);
if (res)
{
printf("Could not request LPC port.\n -%x", res);
return 1;
}
printf("End\n", res);
I am trying to program a Direct2D desktop app based on a Windows tutorial, but am having problems creating a SwapChain1. In the code below everything gets initialized until the CreateSwapChainForHwnd. The pointer m_pDXGISwapChain1 stays NULL. All the pointers except pOutput are ComPtrs.
D2D1_FACTORY_OPTIONS options;
ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1), &options, &m_pD2DFactory1);
if(SUCCEEDED(hr))
{
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0 };
hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags,
featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &m_pD3DDevice,
&m_featureLevel, &m_pD3DDeviceContext);
}
if(SUCCEEDED(hr))
hr = m_pD3DDevice.As(&m_pDXGIDevice1);
if(SUCCEEDED(hr))
hr = m_pD2DFactory1->CreateDevice(m_pDXGIDevice1.Get(), &m_pD2DDevice);
if(SUCCEEDED(hr))
hr = m_pD2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_pD2DDeviceContext);
if(SUCCEEDED(hr))
hr = m_pDXGIDevice1->GetAdapter(&m_pDXGIAdapter);
if(SUCCEEDED(hr))
hr = m_pDXGIAdapter->GetParent(IID_PPV_ARGS(&m_pDXGIFactory2));
DXGI_SWAP_CHAIN_DESC1 swapChainDesc1 = {0};
swapChainDesc1.Width = 0;
swapChainDesc1.Height = 0;
swapChainDesc1.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc1.Stereo = false;
swapChainDesc1.SampleDesc.Count = 1;
swapChainDesc1.SampleDesc.Quality = 0;
swapChainDesc1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc1.BufferCount = 2;
swapChainDesc1.Scaling = DXGI_SCALING_NONE;
swapChainDesc1.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc1.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
swapChainDesc1.Flags = 0;
IDXGIOutput *pOutput;
m_pDXGIAdapter->EnumOutputs(0, &pOutput);
if(SUCCEEDED(hr))
hr = m_pDXGIFactory2->CreateSwapChainForHwnd(
static_cast<IUnknown*>(m_pD3DDevice.Get()), m_hwnd, &swapChainDesc1,
NULL, pOutput, &m_pDXGISwapChain1);
if(SUCCEEDED(hr))
hr = m_pDXGIDevice1->SetMaximumFrameLatency(1);
if(SUCCEEDED(hr))
hr = m_pDXGISwapChain1->GetBuffer(0, IID_PPV_ARGS(&m_pDXGIBackBuffer));
If all your pointers are ComPtr, then the call should look like this:
ComPtr<ID3D11Device> d3dDevice;
ComPtr<IDXGIFactory2> dxgiFactory;
// assuming d3dDevice and dxgiFactory are initialized correctly:
ComPtr<IDXGISwapChain1> swapChain;
dxgiFactory->CreateSwapChainForHwnd(d3dDevice.Get(), hWnd, &swapChainDescription, nullptr, nullptr, swapChain.GetAddressOf())
As for your swap chain description, if you're making a non-Windows Store App, you should set
swapChainDescription.Scaling = DXGI_SCALING_STRETCH;
swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
Both of those values are 0, so you can leave them out.
Here is the complete swap chain description that I use:
DXGI_SWAP_CHAIN_DESC1 swapChainDescription = {};
swapChainDescription.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDescription.SampleDesc.Count = 1;
swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDescription.BufferCount = 2;
See this article for full a walkthrough of how to set up Direct2D 1.1 properly - including the CreateSwapChainForHwnd call: http://msdn.microsoft.com/en-us/magazine/dn198239.aspx
Direct2D don't have SwapChain at user level, SwapChain is for Direct3D, I see some DirectX 11 code in your post, do you really want Direct2D? or Direct3D?
I've written a namespace extension (c++). What I want to do now is to copy the windows explorers 'open with' menu. I've implemented my context menu using IContextMenu, IContextMenu2 and IContextMenu3. I build a standard context menu for a dummy file and put the open with submenu into my own menu. What I've done so far is the following:
int AddStdOpenWithMenu(HMENU hmenu, UINT& indexMenu, UINT& idCmdFirst, UINT& idCmdLast, UINT uFlags, CItem* i){
int items = 0;
if(i != 0){
CString filePath = i->GetTempFileDir();
CString fileName = i->getFileName();
if(PathFileExists(filePath)){
if(filePath.Right(1).CompareNoCase(TEXT("\\")) != 0) filePath += TEXT("\\");
filePath += fileName;
// Dumm yerzeugen
wofstream fStream;
fStream.open(filePath, ios::out | ios::app);
fStream.close();
if(PathFileExists(filePath)){
void* ppv = 0;
HRESULT hr;
LPITEMIDLIST pidl;
SFGAOF sfgao;
LPCITEMIDLIST pidlChild;
hr = ::SHParseDisplayName(filePath, NULL, &pidl, 0, &sfgao);
this->stdContextTmpDir = filePath;
if(hr == S_OK){
hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&m_stdPSF, &pidlChild);
if(hr == S_OK){
hr = m_stdPSF->GetUIObjectOf(GetForegroundWindow(), 1, &pidlChild, IID_IContextMenu, NULL, &ppv);
if(hr == S_OK){
this->m_stdCTM = (IContextMenu*)ppv;
IContextMenu2* ctm2 = 0;
hr = this->m_stdCTM->QueryInterface(IID_IContextMenu2,(LPVOID*)&ctm2);
if(hr == S_OK){
HMODULE g = GetModuleHandle(TEXT("shell32.dll"));
if(g != 0){
// "Öffnen mit" Schriftzug ermitteln
int maxBuffer = 1000;
LPTSTR pStr = new TCHAR[maxBuffer];
CString owStr1, owStr2;
int res = LoadString(g, 5376, pStr, maxBuffer);
if(res > 0) owStr1 = pStr;
res = LoadString(g, 5377, pStr, maxBuffer);
if(res > 0) owStr2 = pStr;
if(!owStr1.IsEmpty() || !owStr2.IsEmpty()){
HMENU stdMenu = CreatePopupMenu();
int subIdCmdFirst = idCmdFirst + LASTMI + 1; // hier wird der maximale offset der Items addiert
int ret = ctm2->QueryContextMenu(stdMenu, indexMenu, subIdCmdFirst, idCmdLast, uFlags);
if(HRESULT_SEVERITY(ret) == SEVERITY_SUCCESS){
int count = GetMenuItemCount(stdMenu);
for(int i = 0; i < count; i++){
res = GetMenuString(stdMenu, i, pStr, maxBuffer, MF_BYPOSITION);
if(res > 0){
if(_tcscmp(pStr, owStr1) == 0 || _tcscmp(pStr, owStr2) == 0){
//Öffnen mit Element gefunden
HMENU subMenu = GetSubMenu(stdMenu, i);
if(subMenu != 0){
hr = ctm2->HandleMenuMsg(WM_INITMENUPOPUP, (WPARAM)GetSubMenu(stdMenu,i) , i);
subMenu = GetSubMenu(stdMenu, i);
if(subMenu != 0){
MENUITEMINFO mii;
TCHAR szText[MAX_PATH];
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
_tcscpy(szText, pStr);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU ;
mii.wID = idCmdFirst + MI_OPENWITH;
mii.fType = MFT_STRING;
mii.dwTypeData = szText;
mii.fState = MFS_ENABLED;
mii.hSubMenu = subMenu;
InsertMenuItem( hmenu, indexMenu++, TRUE, &mii);
items = HRESULT_CODE(ret);
}
}else{
MENUITEMINFO stdMi;
stdMi.cbSize = sizeof(stdMi);
stdMi.fMask = MIIM_ID | MIIM_STATE;
stdMi.dwTypeData = 0;
GetMenuItemInfo(stdMenu, i, true, &stdMi);
MENUITEMINFO mii;
TCHAR szText[MAX_PATH];
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
_tcscpy(szText, pStr);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
mii.wID = stdMi.wID;
mii.fType = MFT_STRING;
mii.dwTypeData = szText;
mii.fState = MFS_ENABLED;
InsertMenuItem( hmenu, indexMenu++, TRUE, &mii);
items = HRESULT_CODE(ret);
}
}
}
}
}
}
delete[] pStr;
}
ctm2->Release();
}
}
}
ILFree(pidl);
}
DeleteFile(filePath);
}
}
}
return items;
}
In the handleMenuMsg functions I pass everything to the standard interface and also XP is drawing icons and texts without any problem. In the 'InvokeCommand' I then know if a command for myself is executed or if it came from the standard context menu. So let's say you open a txt file with explorer everything works fine. The problem is as soon as
this->m_stdCMT->InvokeCommand(pici);
is executed and you close the explorer (Win7, x64), it won't close the process anymore. Does anybody know why?
Kind regards,
Michael