I am using MFC MDI application and i am adding two doc templates as shown in code below:
BOOL CEmuDiagnosticsClientApp::InitInstance()
{
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinAppEx::InitInstance();
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
//Added new code
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_STRING_FILTERWINDOW,
RUNTIME_CLASS(CEmuDiagnosticsClientDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CFilterWindow));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
InitContextMenuManager();
InitKeyboardManager();
InitTooltipManager();
CMFCToolTipInfo ttParams;
ttParams.m_bVislManagerTheme = TRUE;
theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
AddDocTemplate(new CMultiDocTemplate(IDR_STRING_SIGNALWINDOW,
RUNTIME_CLASS(CEmuDiagnosticsClientDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CSignalWindow)));
// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
{
delete pMainFrame;
return FALSE;
}
m_pMainWnd = pMainFrame;
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line. Will return FALSE if
// app was launched with /RegServer, /Register, /Unregserver or /Unregister.
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The main window has been initialized, so show and update it
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
return TRUE;
}
I am using this code to iterate over documents and get view classes's reference in my CMainFrame class.
CFilterWindow* p = NULL;
CSignalWindow* p1 = NULL;
for( POSITION pos = AfxGetApp()->GetFirstDocTemplatePosition(); pos != NULL; )
{
CDocTemplate* pTempl = AfxGetApp()->GetNextDocTemplate( pos );
for( POSITION pos1 = pTempl->GetFirstDocPosition(); pos!= NULL; )
{
CDocument* pDoc = pTempl->GetNextDoc( pos1 );
for( POSITION pos2 = pDoc->GetFirstViewPosition(); pos2 != NULL; )
{
CView* pView = pDoc->GetNextView( pos2 );
if( pView->IsKindOf( RUNTIME_CLASS(CFilterWindow) ) )
{
p = (CFilterWindow*)pView;
p->UpdateUI();
// Do what you need with the view...
}
else
{
p1 = (CSignalWindow*)pView;
p1->UpdateUI();
}
}
}
}
Problem is with loop for( POSITION pos2 = pDoc->GetFirstViewPosition(); pos2 != NULL; )
as pDoc->GetFirstViewPosition(); always returning NULL.
It is puzzling me why it is returning NULL.
Can anybody suggest where I am wrong?
Related
I have written quite a few different add-ins now but I keep struggling to get a windows form working on Revit. The program builds fine and I have the dll set up for Revit to access.
Here are the different sections of my code. The program is more extensive than what is seen but I believe that the problem is a reference issue or a problem with my ADDIN file. Maybe there is a different way I need to set up my ADDIN file since I have a windows form in it?? Let me know.
Here is a Dropbox folder with the screenshots in it.
Let me know if there is anything else you need to see. The error in Revit says it has to do with the FullName but I believe I put it in the ADDIN file correctly, and I did it the same as I had for other ADDINs.
Thank you for your help!
[TransactionAttribute(TransactionMode.Manual)]
[RegenerationAttribute(RegenerationOption.Manual)]
public class CicuitChecker : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
//set document variable
Document document = commandData.Application.ActiveUIDocument.Document;
using (Transaction trans = new Transaction(document))
{
trans.Start("Circuit Checker");
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
//run through looped form in case of user not selecting needed fields, and store what family the user wants the program to check
Boolean messedUp = false;
Boolean All = false, lightF = false, recep = false, elecEquip = false, equipCon = false, junc = false, panels = false;
FilteredElementCollector collector = new FilteredElementCollector(doc), collector2 = new FilteredElementCollector(doc);
while (messedUp)
{
CircuitChecker.CircuitCheckerForm form = new CircuitChecker.CircuitCheckerForm();
form.ShowDialog();
//Get application and document objects
foreach (String item in form.getSelectionElementsLB())
{
if (item.Equals("All"))
{
All = true;
break;
}
else if (item.Equals("Lighting Fixtures"))
{
lightF = true;
}
else if (item.Equals("Recepticales"))
{
recep = true;
}
else if (item.Equals("Electrical Equipment (including Panels)"))
{
elecEquip = true;
}
else if (item.Equals("Junctions"))
{
junc = true;
}
else
{
messedUp = true;
TaskDialog.Show("Error", "At least one element must be selected.");
}
}
if (form.getSelectionPlaceLB().Equals("Entire Project"))
{
collector
= new FilteredElementCollector(doc)
.WhereElementIsNotElementType();
collector2
= new FilteredElementCollector(doc)
.WhereElementIsNotElementType();
}
else if (form.getSelectionPlaceLB().Equals("Elements in Current View"))
{
collector
= new FilteredElementCollector(doc, document.ActiveView.Id)
.WhereElementIsNotElementType();
collector2
= new FilteredElementCollector(doc, document.ActiveView.Id)
.WhereElementIsNotElementType();
}
else
{
messedUp = true;
TaskDialog.Show("Error", "A place must be selected.");
}
}
Color color = new Color(138, 43, 226); // RGB
OverrideGraphicSettings ogs = new OverrideGraphicSettings();
OverrideGraphicSettings ogsOriginal = new OverrideGraphicSettings();
ogs.SetProjectionLineColor(color);
int notCircuited = 0;
//ElementId symbolId = family
ElementCategoryFilter lightFilter = new ElementCategoryFilter(BuiltInCategory.OST_LightingFixtures);
ElementCategoryFilter recepFilter = new ElementCategoryFilter(BuiltInCategory.OST_ElectricalFixtures);
ElementCategoryFilter elecEquipFilter = new ElementCategoryFilter(BuiltInCategory.OST_ElectricalEquipment);
//ElementClassFilter filter = new ElementClassFilter(typeof("Junction Boxes - Load"));
//FamilyInstanceFilter juncFilter1 = new FamilyInstanceFilter(doc, );
LogicalOrFilter first = new LogicalOrFilter(lightFilter, recepFilter);
if (All)
{
collector.WherePasses(first);
IList<Element> allArr = collector.ToElements();
foreach (Element e in allArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
collector2.WherePasses(elecEquipFilter);
IList<Element> elecEquipArr = collector.ToElements();
foreach (Element e in elecEquipArr)
{
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_SUPPLY_FROM_PARAM).AsString();
if ((panel.Equals("")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
TaskDialog.Show("Circuit Checker", notCircuited + " lighting fixtures are not circuited in this view.");
trans.Commit();
}
if (!trans.HasEnded())
{
if (lightF)
{
collector.WherePasses(lightFilter);
IList<Element> lightArr = collector.ToElements();
foreach (Element e in lightArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (recep)
{
collector.WherePasses(recepFilter);
IList<Element> recepArr = collector.ToElements();
foreach (Element e in recepArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (elecEquip)
{
collector.WherePasses(elecEquipFilter);
IList<Element> elecEquipArr = collector.ToElements();
foreach (Element e in elecEquipArr)
{
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_SUPPLY_FROM_PARAM).AsString();
if ((panel.Equals("")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
if (junc)
{
collector.WherePasses(recepFilter);
IList<Element> juncArr = collector.ToElements();
foreach (Element e in juncArr)
{
int cirNum = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER).AsInteger();
String panel = e.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM).AsString();
if (!(IsNumeric(cirNum)) || (panel.Equals("")) || (panel.Equals("<unnamed>")))
{
doc.ActiveView.SetElementOverrides(e.Id, ogs);
notCircuited++;
}
else
{
doc.ActiveView.SetElementOverrides(e.Id, ogsOriginal);
}
}
}
TaskDialog.Show("Circuit Checker", notCircuited + " lighting fixtures are not circuited in this view.");
trans.Commit();
}
}
return Result.Succeeded;
}
public static Boolean IsNumeric(Object Expression)
{
if (Expression == null || Expression is DateTime)
return false;
if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
return true;
try
{
if (Expression is string)
Double.Parse(Expression as string);
else
Double.Parse(Expression.ToString());
return true;
}
catch { } // just dismiss errors but return false
return false;
}
}
This code is having the functionality in the 'main class.' I have since moved the functionality to the form class as konrad suggested but am still receiving the FullClassName error in Revit. Please Help!
The schedule data add-in provides a full Visual Studio solution demonstrating how to display a Windows form in a Revit add-in, including the generation of the Windows form on the fly:
http://thebuildingcoder.typepad.com/blog/2012/05/the-schedule-api-and-access-to-schedule-data.html
Here's how I usually set up my Windows Forms based External Commands. Remember that you have to create an External Command, and your addin manifest must point at this class. Then from this class you can launch the Form like so:
[Transaction(TransactionMode.Manual)]
public class SomeCommand : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
// Get application and document objects
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
UIDocument uidoc = uiApp.ActiveUIDocument;
try
{
SomeNamespace.SomeForm form = new SomeNamespace.SomeForm(doc);
form.ShowDialog();
return Result.Succeeded;
}
// Catch any exceptions and display them
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Cancelled;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
}
So I have a Form class that I instantiate from my ExternalCommand and pass Document to its constructor. That way I have access to document when I am interacting with the form later. I wire up all functionality in code behind of the Form.
Agree, the OP's question is why doesn't the addin work...
From looking at the images, it seems like the issue is that Revit is not properly finding the full class name of the command.
It's a little unusual that you don't have your command class wrapped in a namespace (your form class is, for example).
I would recommend wrapping it in a namespace like "circuitchecker" - like your form class.
Then the "full name" in the addin file would become "circuitchecker.circuitchecker"
(the namespace.classname) - this helps Revit distinguish different classes that might have the same name.
side note: I don't believe that putting a URL into the Image/LargeImage fields in the addin will work - but not positive.
I am uploading a document to Document library. Along with this I am creating a field called 'FieldID' by combining 2 values. However I am unable to see this field in the document library and hence unable to query the document with this field.How can I see this field or how can I retrieve documents using this 'FieldID'. This is the code.
if (UploadFile.PostedFile != null || (UploadFile.PostedFile.ToString() != string.Empty))
{
String fileName = UploadFile.PostedFile.FileName.ToString();
string userLogin = SPContext.Current.Web.CurrentUser.LoginName;
Guid siteID = SPContext.Current.Site.ID;
SPDocumentLibrary exposureLibrary = null;
SPList listDoc = null;
SPFolder myLibrary = null;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite oSite = new SPSite(siteID))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
oWeb.AllowUnsafeUpdates = true;
// exposureLibrary
try
{
// Check if the document library already exists
exposureLibrary = (oWeb.Lists[SharepointCommon.Constants.USERINTERFACECUSTOMIZATIONSFEATURERECEIVER_EXPOSURE_DOCUMENTLIBRARY_NAME] as SPDocumentLibrary);
exposureLibrary.ContentTypesEnabled = false;
exposureLibrary.EnableAttachments = false;
exposureLibrary.EnableFolderCreation = false;
exposureLibrary.EnableVersioning = true;
exposureLibrary.NoCrawl = true;
exposureLibrary.OnQuickLaunch = false;
/* create a Text field for ID */
SPFieldText field = (exposureLibrary.Fields["FILEID"] as SPFieldText);
// Check if the field is available
if (field == null)
{
SPFieldText fldID = (SPFieldText)exposureLibrary.Fields.CreateNewField(
SPFieldType.Text.ToString(), "FILEID");
fldID.Required = true;
fldID.MaxLength = 100;
fldID.Hidden = false;
exposureLibrary.Fields.Add(fldID);
}
//exposureLibrary.Update();
myLibrary = exposureLibrary.RootFolder;
}
catch
{
// Determine the GUID of the document library
Guid ExposureDocumentLibraryId = oWeb.Lists.Add(SharepointCommon.Constants.USERINTERFACECUSTOMIZATIONSFEATURERECEIVER_EXPOSURE_DOCUMENTLIBRARY_NAME, SharepointCommon.Constants.USERINTERFACECUSTOMIZATIONSFEATURERECEIVER_EXPOSURE_DOCUMENTLIBRARY_DESCRIPTION, SPListTemplateType.DocumentLibrary);
listDoc = oWeb.Lists[ExposureDocumentLibraryId];
/* create a Text field for ID */
SPFieldText fldID = (SPFieldText)listDoc.Fields.CreateNewField(
SPFieldType.Text.ToString(), "FILEID");
fldID.Required = true;
fldID.MaxLength = 100;
fldID.Hidden = false;
listDoc.Fields.Add(fldID);
// Set properties of the document library
listDoc.ContentTypesEnabled = false;
listDoc.EnableAttachments = false;
listDoc.EnableFolderCreation = false;
listDoc.EnableVersioning = true;
listDoc.NoCrawl = true;
listDoc.OnQuickLaunch = false;
listDoc.Update();
myLibrary = listDoc.RootFolder;
}
// Prepare to upload
Boolean replaceExistingFiles = true;
// Upload document
SPFile spfile = myLibrary.Files.Add(UploadFile.FileName + "(" + ViewState[UIConstants.CUSTOMERID].ToString() + " - "+ViewState[UIConstants.MondiPlantID].ToString()+ ")", UploadFile.FileContent, replaceExistingFiles);
//spfile.Item["FILEID"]= ViewState[UIConstants.CUSTOMERID].ToString() + " _ " + ViewState[UIConstants.MondiPlantID].ToString();
//myLibrary.Item["ID"] = ViewState[UIConstants.CUSTOMERID].ToString() + " _ " + ViewState[UIConstants.MondiPlantID].ToString();
spfile.Item.Update();
oWeb.AllowUnsafeUpdates = false;`enter code here`
// Commit
myLibrary.Update();
// Update the document library
oWeb.Update();
}
}
});
}
exposureLibrary.Fields.Add(fldID); //after this step
//exposureLibrary.Update();
you need to uncomment this, because after a field is created in try block, list/library is not being updated
I am working on an MDI application where I have 2 views. Here is code to add views and document:
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_STRING_FILTERWINDOW,
RUNTIME_CLASS(CEmuDiagnosticsClientDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CFilterWindow));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
//adding another template
CMultiDocTemplate* pDocTemplate1;
pDocTemplate1 = new CMultiDocTemplate(IDR_STRING_SIGNALWINDOW,
RUNTIME_CLASS(CEmuDiagnosticsClientDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CSignalWindow));
if (!pDocTemplate1)
return FALSE;
AddDocTemplate(pDocTemplate1);
I have 2 views and 1 Document.
My requirement is to update CSignalWindow view based on some notification. When I run this application, I have opened a CSignalWindow view and to update this I have written following piece of code:
for( POSITION pos = AfxGetApp()->GetFirstDocTemplatePosition(); pos != NULL; )
{
pTempl = AfxGetApp()->GetNextDocTemplate(pos );
for( POSITION pos1 = pTempl->GetFirstDocPosition(); pos!= NULL; )
{
if (pos1 == NULL)
break;
CDocument* pDoc = pTempl->GetNextDoc( pos1 );
for( POSITION pos2 = pDoc->GetFirstViewPosition(); pos2 != NULL; )
{
CView* pView = pDoc->GetNextView( pos2 );
if( pView->IsKindOf( RUNTIME_CLASS(CSignalWindow) ) )
{
pView->UpdateData(true);
}
}
}
}
But pos1 is always coming NULL at this line:
for( POSITION pos1 = pTempl->GetFirstDocPosition(); pos!= NULL; )
I am unable to understand why it is returning NULL always?
There is copy-paste-error in this line:
POSITION pos1 = pTempl->GetFirstDocPosition(); pos!= NULL; )
It should be:
POSITION pos1 = pTempl->GetFirstDocPosition(); pos1!= NULL; )
I am using an MFC MDI application. I want to close all child windows on a notification. For this purpose, I am using this code:
CMDIFrameWnd *pFrame = NULL;
CMDIChildWnd *pChild = NULL;
CDocTemplate* pDocTemplate = NULL;
CDocument* pDoc = NULL;
for (POSITION pos = AfxGetApp()->GetFirstDocTemplatePosition(); pos != NULL; )
{
pDocTemplate = AfxGetApp()->GetNextDocTemplate( pos );
for (POSITION pos1 = pDocTemplate->GetFirstDocPosition(); pos1 != NULL; )
{
if (pos1 == NULL)
break;
CDocument* pDoc = pDocTemplate->GetNextDoc( pos1 );
for (POSITION pos2 = pDoc->GetFirstViewPosition(); pos2 != NULL; )
{
CView* pView = (CSignalWindow*)pDoc->GetNextView( pos2 );
pView->CloseWindow();
}
}
}
When this code is executed, in debug mode, it looks its closing all window and UI show black screen in entire child window area.
I want to update this window area after closing all child windows.
How I can update this area?
You should not close the view. Just close the parent frame.
for (POSITION posTemplate = AfxGetApp()->GetFirstDocTemplatePosition(); pos != NULL; )
{
pDocTemplate = AfxGetApp()->GetNextDocTemplate(posTemplate);
POSITION posDoc;
while (posDoc = pDocTemplate->GetFirstDocPosition())
{
CDocument* pDoc = pDocTemplate->GetNextDoc(posDoc);
POSITION posView;
while (posView=pDoc->GetFirstViewPosition())
{
CView* pView = pDoc->GetNextView(posView);
pView->GetParentFrame()->DestroyWindow();
}
}
}
Because you want to close all, you just need to get the head of the lists and remove it.
Using DestroyWindow for the frame may delete more than one view, if you collect views in one child frame (ie. splitter window).
There should never be a problem in repainting, because the parent window always redraws its client area, when a child window is destroyed, as long as you don't use SetRedraw...
In these example, I want to print the contents in the ID tab_form_1.While trying these
sample to print the tab_form_1 contents,lpOleCommandTarget become NULL while query interface using CComptr .
How to solve this issue?
SAMMPLE
IHTMLDocument2 *pDoc;
GetDHtmlDocument(&pDoc);
CComPtr<IHTMLElement2> spControl;
if(GetElementInterface(_T("tab_form_1") ,&spControl) != S_OK)
return;
//ole command target
LPOLECOMMANDTARGET lpOleCommandTarget = NULL;
spControl->QueryInterface(IID_IOleCommandTarget,(void**)&lpOleCommandTarget);ASSERT(lpOleCommandTarget);
//lpDispatch->Release();
if(lpOleCommandTarget == NULL) return;
//prepare header
CString header = _T("Project Path: &w");
VARIANT header_variant;
VariantInit(&header_variant);
V_VT(&header_variant) = VT_BSTR;
V_BSTR(&header_variant) = CString(header).AllocSysString();
//prepare footer
CString footer = _T("&d &t&b Page&p of &P");
VARIANT footer_variant;
VariantInit(&footer_variant);
V_VT(&footer_variant) = VT_BSTR;
V_BSTR(&footer_variant) = CString(footer).AllocSysString();
//prepare header footer safe arrray
SAFEARRAYBOUND parameter_array_bound[1];
SAFEARRAY *parameter_array = NULL;
parameter_array_bound[0].cElements = 2;
parameter_array_bound[0].lLbound = 0;
parameter_array = SafeArrayCreate(VT_VARIANT,1,parameter_array_bound);
//HRESULT hr;
long index;
index = 0;
HRESULT hr = SafeArrayPutElement(parameter_array,&index,&header_variant);
index = 1;
hr = SafeArrayPutElement(parameter_array,&index,&footer_variant);
VARIANT parameter;
VariantInit(¶meter);
V_VT(¶meter) = VT_ARRAY | VT_BYREF;
V_ARRAY(¶meter) = parameter_array;
// print contents of web browser control
lpOleCommandTarget->Exec(NULL, OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, ¶meter,NULL);
//clear all variants
VariantClear(&header_variant);
VariantClear(&footer_variant);
if (parameter_array != NULL) {
SafeArrayDestroy(parameter_array);
}
lpOleCommandTarget->Release();
Try this sample.This will eradicate your problem.This code will print the particular contents into the newly created document.
// create DHtmlDocument for Newly Created Dialog
HRESULT hDispatch = printdlg->m_pBrowserApp->get_Document((IDispatch**)&pDisp);
if(hDispatch != S_OK) return;
HRESULT hResult = pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pNewDoc);
if(hResult != S_OK) return;
//GetDHtmlDocument for new document
GetDHtmlDocument(&pDoc);
BSTR strSummaryText = GetElementHtml(L"tab_form_1");
// Creates a new one-dimensional array
SAFEARRAY *psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
if (psaStrings == NULL) {
return;
}
VARIANT *param;
HRESULT hresult = SafeArrayAccessData(psaStrings, (LPVOID*)¶m);
param->vt = VT_BSTR;
param->bstrVal = strSummaryText;
hresult = SafeArrayUnaccessData(psaStrings);
//it will write the div part of tab_form_1 into new document to pass the summary contents alone to the printer
hresult = pNewDoc->write(psaStrings);
// SafeArrayDestroy calls SysFreeString for each strtemp
if (psaStrings != NULL) {
SafeArrayDestroy(psaStrings);
}