I use windows 7 and VS2010. I write a piece of C++/CLI code to do measurements, during which I want to make screenshot.
I have tried screenshot method in C++ (using GDI library), but failed to compile the file.
So I suppose the GDI library could not be used in C++/CLI.
How to do screenshot and paste to a word in C++/CLI project?
Here is the code:
#include "stdafx.h"
using namespace System;
using namespace System::IO;
int main(array<System::String ^> ^args)
{
String^ fileName = "AP_result.doc";
StreamWriter^ sw = gcnew StreamWriter(fileName);
...
sw->Close();
return 0;
}
I have tried Slawomir Orlowski's method but error occurs:
error
C++/CLI code for screen shot:
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Forms;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
int main(array<System::String ^> ^args)
{
Screen^ r = System::Windows::Forms::Screen::PrimaryScreen;
int width = r->Bounds.Width;
int height = r->Bounds.Height;
Bitmap^ bmp = gcnew Bitmap(width, height, PixelFormat::Format32bppArgb);
Graphics^ screen = Graphics::FromImage(bmp);
screen->CopyFromScreen(0,0,0,0, Size(width, height), CopyPixelOperation::SourceCopy);
bmp->Save("screenshot.bmp");
return 0;
}
In your project you have to add few references: System.Drawing, System.Windows, System.Windows.Forms.
As explained here
https://stackoverflow.com/a/3291411
you need to get context of screen, then put it in bitmap file, it's better explained in answer above, so check answers and comments
Related
Trying to translate to cppwinrt the StorageFolder method GetFilesAsync I'm unable to get past compiler link errors. Here is a very simple routine to test the concept:
#include "winrt/Windows.Storage.h"
#include "winrt/Windows.Foundation.Collections.h"
IAsyncAction TestClass::LoadFiles()
{
StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(hstring(L"Assets"));
auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}
The problem seems to lie in the return type for GetFilesAsync. I've tried various types for that, e.g. IVectorView, but nothing seems to work. Does anyone know of a code example showing how this enumeration might be accomplished in C++/winrt?
[UPDATE] Returning to this project with SDK 10.0.17666 and VS 15.9.0 Preview 3 I find that the solution adopted earlier from these answers no longer works. This time I will be sure to include the full error to see if anyone has ideas. For simplicity I'll use just the simple code provided by IInspectable, altered only to make it a class member in my ResourceManager class:
#include "winrt/Windows.ApplicationModel.h"
#include "winrt/Windows.Storage.h"
#include "winrt/Windows.Storage.Streams.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Storage.Search.h"
#include "winrt/Windows.UI.Core.h"
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;
using namespace Windows::Storage::Search;
IAsyncAction ResourceManager::LoadActivities()
{
StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(L"Activities");
auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}
The call to GetFilesAsync now produces the following link error:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: struct winrt::Windows::Foundation::IAsyncOperation > __thiscall winrt::impl::consume_Windows_Storage_Search_IStorageFolderQueryOperations::GetFilesAsync(enum winrt::Windows::Storage::Search::CommonFileQuery const &)const " (?GetFilesAsync#?$consume_Windows_Storage_Search_IStorageFolderQueryOperations#UStorageFolder#Storage#Windows#winrt###impl#winrt##QBE?AU?$IAsyncOperation#U?$IVectorView#UStorageFile#Storage#Windows#winrt###Collections#Foundation#Windows#winrt###Foundation#Windows#3#ABW4CommonFileQuery#Search#Storage#63##Z) referenced in function "public: struct winrt::Windows::Foundation::IAsyncAction __thiscall AppEngine::ResourceManager::LoadActivities$_ResumeCoro$2(void)" (?LoadActivities$_ResumeCoro$2#ResourceManager#AppEngine##QAE?AUIAsyncAction#Foundation#Windows#winrt##XZ)
(followed by the path to the object file)
I have to admit I find that error message hard to decipher. Perhaps someone else here will have an idea? Must be something that changed in recent system updates.
For what it's worth, the following standalone code builds just fine. So you're probably either missing a #include or a link library, but it's impossible to tell when you don't share important information like what actual error(s) you're seeing.
#pragma comment(lib, "WindowsApp")
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Search.h>
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;
using namespace Windows::Storage::Search;
IAsyncAction LoadFiles()
{
StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(L"Assets");
auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}
int main()
{
LoadFiles().get();
}
I have C++/CLI console application that uses direct sound. I am unsure if directsound is a problem or not, but after Windows 10 update application hangs before even launching. To reproduce this problem please create C++/CLI console application, link it against dsound.lib and copy paste this code into main file. You will notice that it unhangs as soon as DirectSoundEnumerate is commented.
#include "stdafx.h"
#include <vector>
#include <Windows.h>
#include <dsound.h>
using namespace System;
using namespace System::Collections::Generic;
static BOOL CALLBACK DSEnumOutputProc(LPGUID lpGUID,
LPCWSTR lpszDesc,
LPCWSTR lpszDrvName,
LPVOID lpContext)
{
return(TRUE);
}
void EnumerateDirectSoundDevices()
{
if (SUCCEEDED(DirectSoundEnumerate(&DSEnumOutputProc, LPVOID(NULL))))
{
printf("output devices enumerated.\n");
}
}
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Hello World");
return 0;
}
I'm trying to embed mono in a c++ executable, and mono crashes on Assembly.GetExecutingAssembly. Any idea of what I missed ?
EDIT : using mono 3.0.3
EmbeddedMonoTest.cpp :
// EmbeddedMonoTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
int _tmain(int argc, _TCHAR* argv[])
{
MonoDomain* domain = mono_jit_init_version ("ClassLibrary1", "v4.0.30319");
MonoAssembly* _assembly_fbmonoengine = mono_domain_assembly_open (domain, "ClassLibrary1.dll");
MonoImage* _image_fbmonoengine = mono_assembly_get_image (_assembly_fbmonoengine);
MonoClass* klass = mono_class_from_name(_image_fbmonoengine, "ClassLibrary1", "Class1");
MonoMethod* test = mono_class_get_method_from_name(klass, "Test" , 0);
mono_runtime_invoke(test, NULL, NULL, NULL);
return 0;
}
Class1.cs :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace ClassLibrary1
{
public class Class1
{
public static void Test()
{
Assembly.GetExecutingAssembly();
}
}
}
The error :
Unhandled exception at 0x65ad2148 in EmbeddedMonoTest.exe: 0xC0000005: Access violation reading location 0x`00000008.
You're not executing any assembly in your program, so ExecutingAssembly in that context has no meaning (a better error is needed, though).
You need to provide the usual static Main() entry point in the assembly and execute it with mono_runtime_exec_main().
there is any way to have an execution file (*.exe) that run in a folder that doesn't have the dlls referenced by the project??
for example:
using namespace System;
using namespace dllNet;
int main(array<System::String ^> ^args)
{
dllNet::Class1::SayHi();
Console::WriteLine(L"Hello World");
return 0;
}
i want to execute my project without dllNet.dll
No, unfortunately, the program cannot run without the libraries needed.
I want to load two assemblies from C++/CLI; assembly A depends on assembly B, and both are VB.Net projects (3.5). I want them to load from a byte array, so I use Assembly::Load(), but when I try to instantiate a class from assembly A, the framework ignores the previously loaded assembly B and attempts to load it again, which fails because it is not in the search path. The "Name" of the assembly is the same, so I don't know why it fails. For testing purposes, my program loads the bytes directly from the compiled image, but the real code will be loaded differently. This is my test code:
#include "stdafx.h"
using namespace System;
using namespace System::Windows::Forms;
using namespace System::IO;
using namespace System::Reflection;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
array<unsigned char>^ bytes;
FileStream^ f;
f = gcnew FileStream(L"c:\\...\\AssemblyB.dll", FileMode::Open);
bytes = gcnew array<unsigned char>((int)f->Length);
f->Read( bytes, 0, (int) f->Length );
f->Close();
f = nullptr;
Assembly^ assemblyb = Assembly::Load(bytes);
f = gcnew FileStream(L"c:\\...\\AssemblyA.dll", FileMode::Open);
bytes = gcnew array<unsigned char>((int)f->Length);
f->Read( bytes, 0, (int) f->Length );
f->Close();
f = nullptr;
Assembly^ assemblya = Assembly::Load(bytes);
bytes = nullptr;
// Here I get the file not found exception!
Object^ mf = assemblya->CreateInstance(L"AssemblyA.MainForm");
// This line is not reached unless I copy assemblyb.dll to my app's folder:
mf->GetType()->InvokeMember(L"ShowDialog",BindingFlags::Default | BindingFlags::InvokeMethod,
mf->GetType()->DefaultBinder, mf, nullptr );
return 0;
}
The error is:
Could not load file or assembly 'AssemblyB, Version=1.0.3650.39903, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
When I check assemblyb->FullName, it says exactly 'AssemblyB, Version=1.0.3650.39903, Culture=neutral, PublicKeyToken=null'.
Of course, if I copy AssemblyB.dll to my test program's folder the code works just fine, but that's not what I want.
Any ideas?
(By the way, my second step will be attempt to make AssemblyA use classes that my C++/CLI exe will expose.)
OK, I just embarrased myself. It's all in the docs.
// This class is just for holding a managed static variable for assemblyB
ref class Resolver {
public:
static Assembly^ assemblyB;
};
// This is the delegate for resolving assemblies
Assembly^ ResolveHandler(Object^ Sender, ResolveEventArgs^ args)
{
// Warning: this should check the args for the assembly name!
return Resolver::assemblyB;
}
.
.
.
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Set up the handler for the AssemblyResolve event
AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler( ResolveHandler );
.
.
.
// Load assemblyb into the static variable available to the resolver delegate
Resolver::assemblyb = Assembly::Load(bytes);
.
.
.
I hope someone finds this useful. :)