A wonderful tool that has been broken for a long time. It appears that someone has finally updated it: https://github.com/lucasg/Dependencies (finally, like Dec 2019, but OK)
Will's tech tips
Monday, September 21, 2020
Wednesday, March 16, 2016
HTML display on a dialog (MFC)
There is a serious disconnect in the MFC with HTML formatted strings and displaying them on anything *other* than a pure HTMLedit control or HTML Doc/View based full frame windows. I have no idea how they got to that point, but the lack is extreme. Of course, people will point out that moving to Qt, wx, or .NET would address this, but the realities of legacy code make this a tough bite to chew.
So here is a solution, imperfect, but workable: Subclass an existing dialog control (I use a picture control in this example) as a HTMLView. The idea and following implementation is an amalgam of a number of things I found searching for solutions and altered based on failures in use. The major contribution was Jean-Claude Lanz.
CView* m_pView;
CWnd* CreateNewView(CCreateContext* pContext, CWnd *pParent, CRect& rect, int wID)
{
CWnd* pWnd = NULL;
if (pContext != NULL)
{
if (pContext->m_pNewViewClass != NULL)
{
pWnd = (CWnd*)pContext->m_pNewViewClass->CreateObject();
if (pWnd == NULL)
{
TRACE1("Error: Dynamic create of view %Fs failed\n", pContext->m_pNewViewClass->m_lpszClassName);
return NULL;
}
ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CWnd)));
if (!pWnd->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, rect, pParent, wID, pContext))
{
TRACE0("Error: couldn't create view \n");
return NULL;
}
// send initial notification message
pWnd->SendMessage(WM_INITIALUPDATE);
}
}
return pWnd;
}
CCreateContext cc;
cc.m_pNewViewClass = RUNTIME_CLASS(CHtmlView);
cc.m_pCurrentDoc = NULL;
cc.m_pNewDocTemplate = NULL;
cc.m_pLastView = NULL;
cc.m_pCurrentFrame = NULL;
m_pView = (CHtmlView*)CreateNewView(&cc, this, CRect(0, 0, 0, 0), 0);
if (m_pView == NULL)
EndDialog(IDCANCEL);
CRect rect;
GetDlgItem(IDC_HTML)->GetWindowRect(&rect);
ScreenToClient(rect);
m_pView->MoveWindow(&rect);
std::ofstream myfile;
myfile.open ("/blah/blah/v.html");
myfile << *html text string from memory here*;
myfile.close();
((CHtmlView*)m_pView)->Navigate2("file:///blah/blah/v.html");
Of course any number of changes on the views properties can be set to change appearance.
So here is a solution, imperfect, but workable: Subclass an existing dialog control (I use a picture control in this example) as a HTMLView. The idea and following implementation is an amalgam of a number of things I found searching for solutions and altered based on failures in use. The major contribution was Jean-Claude Lanz.
- Add a picture control to your dialog in the area you want the view to appear (IDC_HTML in this example).
- Add afxhtml.h to your stdafx.h:
- Add a member variable to the dialog class for holding the view:
CView* m_pView;
- Add the following construction function (swiped from ) to the top of your cpp file for your dialog:
CWnd* CreateNewView(CCreateContext* pContext, CWnd *pParent, CRect& rect, int wID)
{
CWnd* pWnd = NULL;
if (pContext != NULL)
{
if (pContext->m_pNewViewClass != NULL)
{
pWnd = (CWnd*)pContext->m_pNewViewClass->CreateObject();
if (pWnd == NULL)
{
TRACE1("Error: Dynamic create of view %Fs failed\n", pContext->m_pNewViewClass->m_lpszClassName);
return NULL;
}
ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CWnd)));
if (!pWnd->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, rect, pParent, wID, pContext))
{
TRACE0("Error: couldn't create view \n");
return NULL;
}
// send initial notification message
pWnd->SendMessage(WM_INITIALUPDATE);
}
}
return pWnd;
}
- In your OnInit() create a context:
CCreateContext cc;
cc.m_pNewViewClass = RUNTIME_CLASS(CHtmlView);
cc.m_pCurrentDoc = NULL;
cc.m_pNewDocTemplate = NULL;
cc.m_pLastView = NULL;
cc.m_pCurrentFrame = NULL;
- ...Create the View
m_pView = (CHtmlView*)CreateNewView(&cc, this, CRect(0, 0, 0, 0), 0);
if (m_pView == NULL)
EndDialog(IDCANCEL);
- ...place the View in the view rectangle from the picture control:
CRect rect;
GetDlgItem(IDC_HTML)->GetWindowRect(&rect);
ScreenToClient(rect);
m_pView->MoveWindow(&rect);
- Wherever you want to display the HTML:
std::ofstream myfile;
myfile.open ("/blah/blah/v.html");
myfile << *html text string from memory here*;
myfile.close();
((CHtmlView*)m_pView)->Navigate2("file:///blah/blah/v.html");
Of course any number of changes on the views properties can be set to change appearance.
Thursday, August 14, 2014
The 3D elephant in the room
3D printing is all the rage. Consumer equipment aside, the manufacturing concerns have embraced 3D printing. 3D printer accuracy is getting better everyday. There is, however, an issue.
Assuming you are in the 3D printing for creating an iterative process, or reverse engineering (as opposed to just printing instead of casting parts you designed from the ground up) you can only print to the quality of the data you have. Voxeljet had this in one of there puff pieces about a ...um... 'pipe' that was artful and reproduced via their technology: "The customer was pleased at how quickly and accurately the voxeljet machine was able to print even the smallest details such as the minuscule frog motifs on the pipe." Art may be reproducible to a degree, but that would not have been doable with, say, a gear reducer.
High quality 3D printing requires high quality 3D data. You aren't going to get that with the laser scanners that are being offered as a solution.
Assuming you are in the 3D printing for creating an iterative process, or reverse engineering (as opposed to just printing instead of casting parts you designed from the ground up) you can only print to the quality of the data you have. Voxeljet had this in one of there puff pieces about a ...um... 'pipe' that was artful and reproduced via their technology: "The customer was pleased at how quickly and accurately the voxeljet machine was able to print even the smallest details such as the minuscule frog motifs on the pipe." Art may be reproducible to a degree, but that would not have been doable with, say, a gear reducer.
High quality 3D printing requires high quality 3D data. You aren't going to get that with the laser scanners that are being offered as a solution.
Friday, July 6, 2012
Installaware
The 'human readable' scripting may help those who are not programmers, but the control that is expected of a 'real' scripting language is lacking. I also have had it fail to install frameworks that were marked as required. (or it could be failing to identify that they are not fully installed).
Tuesday, April 10, 2012
Windows Installers
It seems that installer builders for Windows have still not matured. This is a very interesting state of affairs. Perhaps this is caused by persons other than engineers being responsible for creating the install packages. I will be evaluating many options over the next while and hope to have a complete report of which tools perform best for which target audience.
Monday, March 12, 2012
SDK Redesign
I have made the decision to redesign from the ground up a SDK for one of my clients. To allow interim use of old methods and use cases I will add a layer on top to mimic the old SDK. This pushes the users to move to new functionality by putting the performance hit on the deprecated functions rather than punishing early adopters of the new SDK.
Friday, August 12, 2011
Heroku Cedar
If you are developing on MINGW32 and looking to deploy to Heroku Cedar, make sure you update your Heroku gem. 2.2.3 was broken, 2.4.1 seems to be working.
Subscribe to:
Comments (Atom)