|
This message board is for managed and mixed-mode C++ programming only: Managed C++ in VC++.NET or C++/CLI. Please post all standard C++ programming questions in the Visual C++ board[^].
cheers,
Chris Maunder
CodeProject.com : C++ MVP
|
|
|
|
|
Hi, I try to convert from C# to C++/Cli. I have a small application in C#. When I try to print the RDLC report directly to printer, I found a c# online-codes.
public static void Print(this LocalReport report, PageSettings pageSettings)
{
string deviceInfo =
$@"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>{pageSettings.PaperSize.Width * 100}in</PageWidth>
<PageHeight>{pageSettings.PaperSize.Height * 100}in</PageHeight>
<MarginTop>{pageSettings.Margins.Top * 100}in</MarginTop>
<MarginLeft>{pageSettings.Margins.Left * 100}in</MarginLeft>
<MarginRight>{pageSettings.Margins.Right * 100}in</MarginRight>
<MarginBottom>{pageSettings.Margins.Bottom * 100}in</MarginBottom>
</DeviceInfo>";
Warning[] warnings;
var streams = new List<Stream>();
var pageIndex = 0;
report.Render("Image", deviceInfo,
(name, fileNameExtension, encoding, mimeType, willSeek) =>
{
MemoryStream stream = new MemoryStream();
streams.Add(stream);
return stream;
}, out warnings);
foreach (Stream stream in streams)
stream.Position = 0;
if (streams == null || streams.Count == 0)
throw new Exception("No stream to print.");
using (PrintDocument printDocument = new PrintDocument())
{
printDocument.DefaultPageSettings = pageSettings;
if (!printDocument.PrinterSettings.IsValid)
throw new Exception("Can't find the default printer.");
else
{
printDocument.PrintPage += (sender, e) =>
{
Metafile pageImage = new Metafile(streams[pageIndex]);
Rectangle adjustedRect = new Rectangle(e.PageBounds.Left - (int)e.PageSettings.HardMarginX, e.PageBounds.Top - (int)e.PageSettings.HardMarginY, e.PageBounds.Width, e.PageBounds.Height);
e.Graphics.FillRectangle(Brushes.White, adjustedRect);
e.Graphics.DrawImage(pageImage, adjustedRect);
pageIndex++;
e.HasMorePages = (pageIndex < streams.Count);
e.Graphics.DrawRectangle(Pens.Red, adjustedRect);
};
printDocument.EndPrint += (Sender, e) =>
{
if (streams != null)
{
foreach (Stream stream in streams)
stream.Close();
streams = null;
}
};
printDocument.Print();
}
}
}
For the above code I convert it like the below, but still need to improve the conversion, any helps please. Thanks. And my converted codes.
public: static System::Void Print(LocalReport^ report, PageSettings^ pageSettings){
String^ deviceInfo =
$@"<DeviceInfo>
<OutputFormat>EMF< / OutputFormat>
<PageWidth>{pageSettings->PaperSize->Width * 100}in< / PageWidth>
<PageHeight>{pageSettings->PaperSize->Height * 100}in< / PageHeight>
<MarginTop>{pageSettings->Margins->Top * 100}in< / MarginTop>
<MarginLeft>{pageSettings->Margins->Left * 100}in< / MarginLeft>
<MarginRight>{pageSettings->Margins->Right * 100}in< / MarginRight>
<MarginBottom>{pageSettings->Margins->Bottom * 100}in< / MarginBottom>
< / DeviceInfo>";
cli::array<Warning^>^ warnings = gcnew cli::array<Warning^>();
cli::array<Stream^>^ streams = gcnew cli::array<Stream^>();
int pageIndex = 0;
report->Render("Image", deviceInfo, (name, fileNameExtension, encoding, mimeType, willSeek) = > {
MemoryStream^ stream = gcnew MemoryStream();
streams->Add(stream);
return stream;
}, out^ warnings);
for each(Stream^ stream in streams) {
stream->Position = 0;
if (streams == nullptr || streams->Length == 0) {
throw gcnew Exception("No stream to print.");
}
else {
PrintDocument^ printDocument = gcnew PrintDocument();
printDocument->DefaultPageSettings = pageSettings;
if (!printDocument->PrinterSettings->IsValid)
throw gcnew Exception("Can't find the default printer.");
else
{
printDocument->PrintPage += (sender, e) = >
{
Metafile^ pageImage = gcnew Metafile(streams[pageIndex]);
Rectangle^ adjustedRect = gcnew Rectangle(e->PageBounds->Left - (int)e->PageSettings->HardMarginX, e->PageBounds->Top - (int)e->PageSettings->HardMarginY, e->PageBounds->Width, e->PageBounds->Height);
e->Graphics->FillRectangle(Brushes->White, adjustedRect);
e->Graphics->DrawImage(pageImage, adjustedRect);
pageIndex++;
e->HasMorePages = (pageIndex < streams->Count);
e->Graphics->DrawRectangle(Pens->Red, adjustedRect);
};
printDocument->EndPrint += (Sender, e) = >
{
if (streams != nullptr)
{
foreach(Stream^ stream in streams)
stream->Close();
streams = nullptr;
}
};
printDocument->Print();
}
}
}
}
|
|
|
|
|
I want to use the Win32Exception class in my C++/CLI DLL. The docs say it is located in the System::ComponentModel namespace.
But Intellisense is telling me that there is no ComponentModel namespace inside System .
And worse, there is no System.ComponentModel DLL to which to add a reference.
I'm stuck. How do I get the System::ComponentModel namespace and its classes into my DLL?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
you might try: Microsoft.Win32.Primitives.dll
There is conflicting / confusing information out there.
I've confirmed the above in C#.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Thanks Gerry.
I have 125 copies of that file on my dev machine. Each one is a different size, date, version and in a different folder.
I think I'll work around not having that exact exception class for now.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
|
hi guys
im working on c++/ cli project and i need something like objectlistview of TreelistView so i can display treeview with multi columns
modified 22-Aug-23 5:13am.
|
|
|
|
|
|
devexpress doesnt support c++/cli
|
|
|
|
|
Sorry, but that was all I could find. You could probably do a more focused search, since you know your exact requirements.
|
|
|
|
|
Temblor wrote: cli project...TreelistView
So 'cli' is command line interface.
So a CUI for a tree list view?
My take is you have three options.
1. Get different requirements so it is not needed at all.
2. The tree is going to be very shallow. And probably very short. So roll your own.
3. This isn't going to work.
Why the third? For example sometimes I recurse a directory tree via the command line looking for files or even all files. I can certainly view that in a console but it is basically worthless because there is so much data. Even if I am just looking for one specific file I still need a search mechanism. So I route to a file and then use an editor to search.
But lets say you are not looking for a actual file system. So what is the growth rate of this tree? If it is shallow and small in 10 years rolling your own still works. And the users can use it. But if your growth rate is not small then in 10 years the users will have something they can't use.
If I was asked to do this and I already knew that the tree was not small then I would push back on the requirements. In writing (like email.) And if they insisted I would first make a copy of that email and my response. Then I would just roll my own (still not that hard.) It would be their problem when it was unusable. But I might use a demo with data from 10 years from now - just so they can see what is going to happen.
|
|
|
|
|
jschell wrote: So 'cli' is command line interface.
No. See .NET programming with C++/CLI | Microsoft Learn[^] for example. It's some bastardisation of "Interface to CLR (Common Language Runtime)".
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
let explain some inf
I succeed in displaying sql data in a treeView all i need now is another column so i can display another data like (balance) in it
something like objectListView
it's not for showing system files
btw I saw some devs made what you taking about (file system in treeView) in C++ / MFC
|
|
|
|
|
jschell wrote: cli project...
So 'cli' is command line interface. The forum, title, and indeed the question specifically stated c++/cli, which is the C++ version of code that compiles into .NET IL.
modified 23-Aug-23 4:23am.
|
|
|
|
|
|
"Columns" are an illusion. If you only have "one column / item / field" (that you can identify), concatenate multiple fields together (as strings) with padding and / or a "separator" (e.g. "|")
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
FINALLY
I MADE IT
|
|
|
|
|
Hi
I am getting a heap corruption. I am running under the visual studio debugger. and the exception is at Quote:
ntdll.dll!RtlReportCriticalFailure() Unknown
My scenario is I have a DLL reading and formatting data for a .exe. I keep a record count so when I get a exception, at Quote: ntdll.dll!RtlReportCriticalFailure() Unknown
I insert code if (recordcount == 0x0000196e) __debugbreak; I then start stepping through the code looking for the problem how ever when stepping through the code works I try this multiple times however when I stop the code where the exception were to occur it always complete successfully
The listing I am trying to to inset in the richedit is huge about 153 pages 30 lines to page, 134 bytes across I roughly calculate the number of bytes I am trying to insert into the richedit is 1.6 meg. I am not sure if the size is the issue I do a Rciheditctrl::LimitText with the amount bytes I need
Again when break on the offending record and step thru the code it completes normally
Here is the stack frame My code starts a the DriveRichedit.exe
ntdll.dll!RtlReportCriticalFailure() Unknown
ntdll.dll!RtlpHeapHandleError() Unknown
ntdll.dll!RtlpHpHeapHandleError() Unknown
ntdll.dll!RtlpLogHeapFailure() Unknown
ntdll.dll!RtlpHeapFindListLookupEntry() Unknown
ntdll.dll!RtlpFindEntry() Unknown
ntdll.dll!RtlpAllocateHeap() Unknown
ntdll.dll!RtlpAllocateHeapInternal() Unknown
riched20.dll!CTxtArray::AddBlock(long,long) Unknown
riched20.dll!CTxtArray::SplitBlock(long,long,long,long,int) Unknown
riched20.dll!CTxtPtr::InsertRange(long,unsigned short const *) Unknown
riched20.dll!CRchTxtPtr::ReplaceRange(long,long,unsigned short const *,class IUndoBuilder *,long,long *,unsigned long) Unknown
riched20.dll!CTxtRange::ReplaceRange(long,unsigned short const *,class IUndoBuilder *,enum SELRR,long *,unsigned long) Unknown
riched20.dll!CTxtRange::CheckLimitReplaceRange(long,unsigned short const *,int,class IUndoBuilder *,unsigned long,long *,long,int,unsigned long) Unknown
riched20.dll!CTxtRange::CleanseAndReplaceRange(long,unsigned short const *,int,class IUndoBuilder *,unsigned short *,long *,unsigned long) Unknown
riched20.dll!CLightDTEngine::ReadPlainText(class CTxtRange *,struct _editstream *,int,class IUndoBuilder *,long) Unknown
riched20.dll!CLightDTEngine::LoadFromEs(class CTxtRange *,long,struct _editstream *,int,class IUndoBuilder *) Unknown
riched20.dll!CTxtEdit::TxSendMessage(unsigned int,unsigned __int64,__int64,__int64 *) Unknown
riched20.dll!RichEditWndProc() Unknown
riched20.dll!RichEditANSIWndProc() Unknown
user32.dll!UserCallWinProcCheckWow() Unknown
user32.dll!CallWindowProcAorW(__int64 ,struct HWND__ *,enum _WM_VALUE,unsigned __int64,__int64,int) Unknown
user32.dll!CallWindowProcA() Unknown
mfc140d.dll!CWnd::DefWindowProcA(unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 1100 C++
mfc140d.dll!CWnd::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2100 C++
mfc140d.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 265 C++
mfc140d.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 418 C++
mfc140d.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 299 C++
user32.dll!UserCallWinProcCheckWow() Unknown
user32.dll!SendMessageWorker() Unknown
user32.dll!SendMessageInternal(struct HWND__ *,unsigned int,unsigned __int64,__int64,int) Unknown
user32.dll!SendMessageA() Unknown
mfc140d.dll!CRichEditCtrl::StreamIn(int nFormat, _editstream & es) Line 775 C++
> DriveRichEdit.exe!CProgDebug::OnInitDialog() Line 136 C++
[External Code]
DriveRichEdit.exe!CMainFrame::PROGDEBUG() Line 48 C++
[External Code]
DriveRichEdit.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 26 C++
[External Code]
|
|
|
|
|
I am curios, are you using the MFC code in a Managed C++/CLI application?
|
|
|
|
|
I’m not apparently I posted in the wrong forum I meant to post in the MFC forum
|
|
|
|
|
Hi
I have been looking at the examples off dll and TLS
First thing I noticed that
DWORD g_dwThreadIndex; is in global storage
It would be nice as in the IBM manuals would have registers on at entry to DllMain
I mean is the SP (register) that of the calling application
regardless if the index returned from tlsalloc lets say is 5
and then before the current thread access the storage set by tlssetvalue
another thread does a tlsallloc g_dwThreadindex becomes 6
then the first thread then does tlsgetvalue it would be using 6 instead of 5 obviously I am not understanding something
I mean if gw_dwThreadindex would be defined in the callers stack I would get it
more so is the anyway of knowing the identity of the caller I mean maybe process id or thread guess I could do a call to Startupinfo
|
|
|
|
|
We don't know which examples you've been looking at. But the whole point of thread-local storage is that it's local to the thread; one thread cannot modify a TLS variable for another thread. (At least not without jumping through several flaming hoops whilst drenched in LPG and holding a large firework.)
Each thread gets its own copy of the TLS variable. If thread A set it to 5, and thread B sets it to 6, thread A will still see it set to 5.
Thread Local Storage | Microsoft Learn[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I am refering to the following example i found in the codeproject my lack of understanding is due to the fact that gw_dwThreadIndexis defined in global storage not stack/local storage
Shrink ▲
struct ThreadData {
};
...
DWORD g_dwThreadIndex;
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance,
DWORD dwReason, LPVOID )
{
ThreadData* pData;
switch (dwReason) {
case DLL_PROCESS_ATTACH:
g_dwThreadIndex = ::TlsAlloc();
if (g_dwThreadIndex == TLS_OUT_OF_INDEXES)
return FALSE;
case DLL_THREAD_ATTACH:
pData = (ThreadData*) ::LocalAlloc(LPTR, sizeof(ThreadData));
if (pData == 0)
return FALSE;
::TlsSetValue(g_dwThreadIndex, (LPVOID) pData);
break;
case DLL_THREAD_DETACH:
pData = (ThreadData*) ::TlsGetValue(g_dwThreadIndex);
if (pData != 0)
::LocalFree((HLOCAL) pData);
break;
case DLL_PROCESS_DETACH:
pData = (ThreadData*) ::TlsGetValue(g_dwThreadIndex);
if (pData != 0)
::LocalFree((HLOCAL) pData);
::TlsFree(g_dwThreadIndex);
break;
}
return TRUE;
}
...
};
|
|
|
|
|
I'm not a C++ person, but as far as I can see, the only place you write to the g_dwThreadIndex variable is in the DLL_PROCESS_ATTACH code. According to Microsoft, that means:
The DLL is being loaded into the virtual address space of the current process as a result of the process starting up or as a result of a call to LoadLibrary . DLLs can use this opportunity to initialize any instance data or to use the TlsAlloc function to allocate a thread local storage (TLS) index.
As far as I can see, that will only ever happen once per process. And the documentation explicitly says that this is the correct time to call TlsAlloc .
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Just realized posted to wrong forum however the variable is in static or global storage the next thread that comes by can change its value thats my problem just about all the. examples for TLS and DLL s have it this way
|
|
|
|
|