I've been trying to use TDirect2D in my c++ builder project. I've been using the following code to gain access to Direct2D Canvas.
void __fastcall TCustomDrawPanel::Paint()
{
if ( TDirect2DCanvas::Supported() )
{
std::unique_ptr<TDirect2DCanvas> D2DC(
new TDirect2DCanvas( Canvas, ClientRect )
);
struct DrawSession {
explicit DrawSession( TDirect2DCanvas& Canvas )
: c_( Canvas ) { c_.BeginDraw(); }
~DrawSession() {
try {
c_.EndDraw();
}
catch ( ... ) {
}
}
TDirect2DCanvas& c_;
}
D2DSession( *D2DC );
DDrawPanel(D2DC);
}
This code works fine, but the Direct2D resources have to be acquired and released on each repaint. So I'm using the example found On Embarcadero website. For that example to work properly I'll have to resize the render target when ever the window is resized. The example given on the website is in Delphi as shown below.
procedure T2D2Form.WMSize(var Message: TWMSize);
begin
if Assigned(FCanvas) then
ID2D1HwndRenderTarget(FCanvas.RenderTarget).Resize(D2D1SizeU(ClientWidth,
ClientHeight));
inherited;
end;
My question is how can I convert this to c++ builder code? I've tried many different ways to cast FCanvas->RenderTarget but the code won't compile.
I've tried the following:
ID2D1HwndRenderTarget * target =
dynamic_cast < Winapi::D2d1::ID2D1HwndRenderTarget * > (FCanvas->RenderTarget);
I can use target->Resize(D2D1SizeU(ClientWidth, ClientHeight)) to change render size if I can get the code to compile.
Related
I am attempting to load a wxIcon in Windows by loading from a system DLL (as the mime system told me that the icon for such a file type was in the DLL), eg.
wxIcon icon;
icon.LoadFile("C:\\WINDOWS\\system32\\zipfldr.dll", wxICON_DEFAULT_TYPE);
This fails but I was wondering if there was any way in the codebase of loading this, other than resorting to native Win32 functions.
Also, if there are native Win32 functions, does anyone know what they are?
EDIT: I have tried the following with no success:
::wxInitAllImageHandlers();
wxMimeTypesManager manager;
wxFileType* type = manager.GetFileTypeFromExtension("sys");
wxIconLocation location;
if (type->GetIcon(&location))
{
// location is something like C:\WINDOWS\system32\imageres.dll
wxIcon icon;
if (!icon.LoadFile(location.GetFileName(), wxBITMAP_TYPE_ICON /*I have tried wxICON_DEFAULT_TYPE too*/))
{
// Failed!
}
}
EDIT 2: In response to VZ, I have tried the following with no success sadly:
::wxInitAllImageHandlers();
wxMimeTypesManager manager;
wxFileType* type = manager.GetFileTypeFromExtension("sys");
wxIconLocation location;
if (type->GetIcon(&location))
{
// location is something like C:\WINDOWS\system32\imageres.dll,
//with an appropriate index as retrieved by location.GetIndex(), which is -67.
wxIcon icon(location);
if (!icon.IsOk())
{
BREAK;
// Failed!
}
}
EDIT 3:
Thanks for everyone's help - works fine if I use wxBITMAP_TYPE_ICO instead of wxBITMAP_TYPE_ICON (notice the N), and also I was putting my test code in my app's constructor instead of in ::OnInit. It worked in OnInit but not in the constructor so that's a lesson learned!
Thanks everyone for the help and speedy responses, much appreciated as always.
It should work if you specify type wxBITMAP_TYPE_ICO.
The first argument to LoadFile() must specify the icon resource ID when using wxBITMAP_TYPE_ICO (which is indeed what you need to use when loading icons from files, and not resources of the current module), i.e. you're also missing the ;N part at the end, where N is the value returned by wxFileTypeInfo::GetIconIndex().
But to avoid dealing with this explicitly, you should just use wxFileType::GetIcon() and construct wxIcon from the wxIconLocation filled in by it.
For example, this:
diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 0d91f7fc75..3623aacc56 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
## -123,6 +123,12 ## bool MyApp::OnInit()
if ( !wxApp::OnInit() )
return false;
+ wxIcon icon(wxIconLocation(R"(c:\Windows\system32\imageres.dll)", -67));
+ if ( icon.IsOk() )
+ {
+ wxLogMessage("Loaded icon of size %d*%d", icon.GetWidth(), icon.GetHeight());
+ }
+
// create the main application window
MyFrame *frame = new MyFrame("Minimal wxWidgets App");
shows the expected message about loading the icon of size 32 by 32.
I am using the "DirectX 11 and XAML App (Universal Window)" template in vs2015. I want to get user's keystroke in every frame. So I tried to put GetAsyncKeyState() inside of the render-loop. The render-loop is running in a separate thread:
auto workItemHandler = ref new WorkItemHandler([this](IAsyncAction ^ action)
{
// Calculate the updated frame and render once per vertical blanking interval.
while (action->Status == AsyncStatus::Started)
{
critical_section::scoped_lock lock(m_criticalSection);
Update();
m_sceneRenderer->OnKeyDown();
if (Render())
{
m_deviceResources->Present();
}
}
});
// Run task on a dedicated high priority background thread.
m_renderLoopWorker = ThreadPool::RunAsync(workItemHandler, WorkItemPriority::High, WorkItemOptions::TimeSliced);
m_sceneRenderer->OnKeyDown() is where I put GetAsyncKeyState(). But whenever I put m_sceneRenderer->OnKeyDown() inside the while loop, all the DirectX content will not be rendered. Also, m_renderLoopWorker will be nullptr and throw an exception when I close the application.
// Sample3DSceneRenderer.h, truncated
namespace UWP_DX11_XAML_
{
class Sample3DSceneRenderer
{
Sample3DSceneRenderer(Windows::UI::Core::CoreWindow^ window);
void OnKeyDown();
Platform::Agile<Windows::UI::Core::CoreWindow^> m_window;
}
}
// Sample3DSceneRenderer.cpp, truncated
UWP_DX11_XAML_::Sample3DSceneRenderer::Sample3DSceneRenderer(
Windows::UI::Core::CoreWindow^ window):
m_window(window)
{
}
void UWP_DX11_XAML_::Sample3DSceneRenderer::OnKeyDown()
{
m_window.Get()->GetAsyncKeyState(Windows::System::VirtualKey::Control);
}
Calling other member functions of m_window can cause the same problem.
You may wish to setup a dedicated input thread using CreateCoreIndependentInputSource(CoreInputDeviceTypes::Mouse | CoreInputDeviceTypes::Touch | CoreInputDeviceTypes::Pen);
There's a sample here which demonstrates this option: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/LowLatencyInput
I also found these similar articles which discuss optimizing for low input latency.
https://learn.microsoft.com/en-us/windows/uwp/gaming/optimize-performance-for-windows-store-direct3d-11-apps-with-coredispatcher
https://blogs.windows.com/buildingapps/2013/12/18/optimizing-directx-apps-for-low-latency-input-and-longer-battery-life/#JPGhHjXExbySmTf7.97
I'm making a thread software with VTK, where I need to change the model itself in real time, while I need to change his method of rendering. Everything is working fine, but, the problem start with the interactor->start(); , the model data gets updated just fine, but it's only showed on screen when I move The camera. Also I have selected some methods for generating a 3D data from a imagedata file, for that I need to close the vtk window (interactor window) and then the code will reopen it and send the new data generated to it...
I would need something like these:
int force close_window = false; int refresh_interactor = false;
I managed to make the Window close, but only with vtkcommand::Keypressed command, but idk how do I do with a new command :S, I tried the vtkcommand::UserEvent but I didn't found a good information about how to deal with that data (like some way to call it)
the way I'm dealing with VTK is with two threads, the first one, is just about the vtk iren loop, and the second one would manage the models and check if iren requires to be updated.
In my dream code it should be something like this:
=======================================================
bool VTKWindow()
{
...
vtkSmartPointer ator = vtkSmartPointer::New();
iren = vtkSmartPointer::New();
RenWindow = vtkSmartPointer::New();
render->SetBackground(.1, .2, .3);
RenWindow->AddRenderer(renderer);
iren->SetRenderWindow(RenWindow);
if(data_type == voxel_type)
{
Render->AddViewProp(VoxelData);
}
else
{
actor->SetMapper(PolyData);
Render->AddActor(Actor);
}
RenWindow->Render();
iren->Start();
}
void ManageVTK()
{
while true loop...
if(force close_window == true)
do some command to exit the iren loop
if(refresh_interactor == true)
do some command to refresh iren
}
Sorry for the english, it's not my native language, and also sorry about the question format, it's the first time I'm using stackoverflow
It may sounds stupid, but, I found a kind of solution for the problem.
I saw on related links this guy vtkRenderWindowInteractor event loop and threading and, it's almost the same problem...
class VTKNewEvent : public vtkCommand{
public:
vtkTypeMacro(VTKNewEvent , vtkCommand);
static VTKNewEvent * New(){
return new VTKNewEvent ;
}
void Execute(vtkObject * caller, unsigned long vtkNotUsed(eventId), void * vtkNotUsed(callData)){
vtkRenderWindowInteractor *iren = static_cast<vtkRenderWindowInteractor*>(caller);
if (iren_close == true){
iren->GetRenderWindow()->Finalize // Stop the interactor
iren->TerminateApp();
iren_close = false;
}
if (iren_update== true){
renderJanela->Render();
iren_update= false;
}
}
};
bool VTKWindow(){
vtkSmartPointer<VTKNewEvent > IrenRefresh= vtkSmartPointer<VTKNewEvent>::New();
...
iren->CreateRepeatingTimer(1);//this makes that IrenRefresh will be called at every 1ms
iren->AddObserver(vtkCommand::TimerEvent, IrenRefresh);
iren->Start();
...
}
it's simple, but, maybe not the best, but it did Th job, I hope this link will help people that are starting into the VTK world, since threads + rendering loop wasn't a simple job to understand what was going on
I build Qt gui and have many windows to handle with.
I implement this meanwhile with QStackedWidgets (replace the window in buttons click signal), but I am not sure this is the right way.
Can I maintain a lot of windows in this technique ?
what is the prefered way / best practice ?
This is piece of my code (relevant):
ui->pagesWidget->addWidget(new Menu);
ui->pagesWidget->addWidget(new Repetitive);
ui->pagesWidget->addWidget(new SinglePulse);
void MainWindow::on_btnSinglePulse_clicked()
{
ui->pagesWidget->setCurrentIndex(1);
}
void MainWindow::on_btnMenu_clicked()
{
ui->pagesWidget->setCurrentIndex(0);
}
void MainWindow::on_btnPulseGroup_clicked()
{
ui->pagesWidget->setCurrentIndex(2);
}
I think it's fine, but maybe you could simplify your code if you create only one slot, and check the sender() in that.
void onButtonClicked()
{
if ( sender() == ui->button0 )
{
ui->pagesWidget->setCurrentIndex( 0 );
}
else if ( sender() == ui->button1 )
{
ui->pagesWidget->setCurrentIndex( 1 );
}
// ... and so on.
}
Or you could just simply use a QTabWidget.
I've installed a Windows XP Professional SP3 on a VMWare image and the Visual Studio 2005 on it. I've created a new dialog based C++ MFC project with /clr support. I've put a RichEdit 2.0 control onto the auto-generated dialog and I'm trying to read up a text file and put its content into this RichEdit 2.0 control by button click without formatting. I've added a variable to the RichEdit 2.0 called pCRichEditCtrl and here is my code which doesn't work.
CWinApp inheritance:
BOOL CTextFormatterApp::InitInstance()
{
...
AfxInitRichEdit2();
CWinApp::InitInstance();
...
}
CDialog inheritance:
void CTextFormatterDlg::OnBnClickedButton1()
{
StreamReader^ objReader = gcnew StreamReader("c:\\text.txt");
String ^sLine = "";
sLine = objReader->ReadLine();
while (sLine != nullptr)
{
pCRichEditCtrl.SetSel(pCRichEditCtrl.GetTextLength(), -1);
pCRichEditCtrl.ReplaceSel(CString(sLine));
sLine = objReader->ReadLine();
}
objReader->Close();
}
I don't know whether it counts but I get the following warnings at linking:
TextFormatterDlg.obj : warning LNK4248: unresolved typeref token (01000016) for 'AFX_CMDHANDLERINFO'; image may not run
TextFormatter.obj : warning LNK4248: unresolved typeref token (01000012) for 'AFX_CMDHANDLERINFO'; image may not run
TextFormatterDlg.obj : warning LNK4248: unresolved typeref token (01000015) for 'IAccessibleProxy'; image may not run
I'm not sure what I'm doing because I'm familiar only with newer frameworks and I don't know either Windows.
Input file exists, I can see the read text if I debug the application but I can't see any changes in the edit box. I've tried to call pCRichEditCtrl.UpdateData(true); but nothing has changed.
Is it enough to add a variable for getting the controller of the box (pCRichEditCtrl)? It seems to the pointer doesn't point to the proper control item.
Do you have any idea what is missing?
There's no need to use CLI to just read text files, try something like:
void CTextFormatterDlg::OnBnClickedButton1()
{ CStdioFile f1;
CString sLine;
if (!f1.Open(_T("c:\\text.txt"), CFile::modeRead | CFile::typeText))
return;
while (f1.ReadString(sLine))
{ pCRichEditCtrl.SetSel(pCRichEditCtrl.GetTextLength(), -1);
pCRichEditCtrl.ReplaceSel(sLine);
}
f1.Close();
}
EDIT: control variable pCRichEditCtrl
a) should be declared in the dialog class as CRichEditCtrl pCRichEditCtrl;
b) should be connected to the ID of the control (e.g.: IDC_RICHEDIT21), like
void CTextFormatterDlg::DoDataExchange(CDataExchange* pDX)
{ CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_RICHEDIT21, pCRichEditCtrl);
}
c) I have tested the following code and it works for me (adds "aa" to the control window on each button click)
pCRichEditCtrl.SetSel(pCRichEditCtrl.GetTextLength(), -1);
pCRichEditCtrl.ReplaceSel(TEXT("aa"));
I share the final solution with the community to be available for those who faces with the same issue. I don't know why do I have to use Update(FALSE); on the CWinApp inheritance two times but it solves everything. If someone has an idea or a better (nicer) solution don't hesitate to share it with us, I'll move the accepted flag to that version (if it is possible, I haven't tried it before).
void CTextFormatterDlg::OnBnClickedButton1()
{
StreamReader^ objReader = gcnew StreamReader("c:\\text.txt");
String ^sLine = objReader->ReadLine();
UpdateData(FALSE); //this is the first unexpected first aid
while (sLine != nullptr)
{
pCRichEditCtrl.SetSel(pCRichEditCtrl.GetTextLength(), -1);
pCRichEditCtrl.ReplaceSel(CString(sLine + "\r\n"));
UpdateData(FALSE); //this is the second unexpected first aid
sLine = objReader->ReadLine();
}
objReader->Close();
}