How to set col width in excel with xlslib - c++

I have a MFC C++(not managed) program and I need to generate a xls.
I'm using xlslib(http://xlslib.sourceforge.net/) version 2.3.4 to generate the xls, but I can't resize excel columns.
The class "worksheet" has the method "colwidth":
void colwidth(unsigned32_t col, unsigned16_t width, xf_t* pxformat = NULL); // sets column widths to 1/256 x width of "0"
I invoked this method passing the parameters (0, 5), (0,20), (0,1000) and (1,5), no one worked :/.
I just need that the column fit the size necessary to display all the text.
Any help will be very useful, I'm lost.

Try the following code:
workbook WorkBook;
worksheet* WorkSheet = WorkBook.sheet(_T("Sheet1"));
WorkSheet->defaultColwidth(8);
WorkSheet->colwidth(0, 256*10);;
WorkSheet->colwidth(1, 256*16);
WorkSheet->rowheight(0, 256*1.0586);
WorkSheet->rowheight(1, 256*2);
I also meet with this problem,i try it many times and discover that before invoke "colwidth" you must firstly invoke "defaultColwidth",the parameter of method "defaultColwidth" must be "8".The codes already work fine on my computer.
I am Chinese,English not mother language,I wish you can understand it.

Related

How to set cell values using Excel12v C interface

I have an Excel12v function using XLOPER to set some values on an Excel sheet. I can create XLLs fine as per Microsoft's XLL guide. I authored xladd-derive for Rust which enables this an allows returning scalars and ranges of values very simply.
However I would like, rather than return a value, to set a random cell to a value. There is xlSet function demonstrated below that does this and works fine.
short WINAPI xlSetExample()
{
XLOPER12 xRef, xValue;
xRef.xltype = xltypeSRef;
xRef.val.sref.count = 1;
xRef.val.sref.ref.rwFirst = 204;
xRef.val.sref.ref.rwLast = 205;
xRef.val.sref.ref.colFirst = 1;
xRef.val.sref.ref.colLast = 1;
xValue.xltype = xltypeInt;
xValue.val.w = 12345;
Excel12v(xlSet, 0, 2, (LPXLOPER12)&xRef, (LPXLOPER12)&xValue);
return 1;
}
but only works if it's called from a VBA macro
Sub test()
Application.Run("xlSetExample","12345")
End Sub
Is there an equivalent xlf* or xlc* function that allows one to set cell values but do not need to be called from a VBA macro
In general, Excel prevents spreadsheet functions from changing the values in cells. In effect, spreadsheet functions are given a read-only view of the values in the sheet.
This is the documentation for xlSet which states:
xlSet behaves as a Class 3 command-equivalent function; that is, it is
available only inside a DLL when the DLL is called from an object,
macro, menu, toolbar, shortcut key, or the Run button in the Macro
dialog box (accessed from View tab on the ribbon starting in Excel
2007, and the Tools menu in earlier versions).
The reason for this is to prevent circular references or other actions that would break or confuse the calculation tree. Excel would struggle to determine dependencies between cells if a function in one cell could change other cells' contents.
Consider the hypothetical function AddOne() which takes a number, adds one and uses this to set the cell immediately to the right via xlSet (or otherwise). What would happen if the formula in cell A1 were =AddOne(B1)?
This Excel SDK reference gives more information. Namely:
Different Types of Functions
Excel4 and Excel12 distinguish among three classes of functions. The
functions are classified according to the three states in which Excel
might call the DLL.
Class 1 applies when the DLL is called from a worksheet as a result of
recalculation.
Class 2 applies when the DLL is called from within a function macro or
from a worksheet where it was registered with a number sign (#) in the
type text.
Class 3 applies when a DLL is called from an object, macro, menu,
toolbar, shortcut key, ExecuteExcel4Macro method, or the
Tools/Macro/Run command. For more information, see Excel Commands,
Functions, and States.
Only Class 3 functions can call xlSet.
So, in summary, the Excel application really doesn't want users to change one cell from a function call in another. As always, if you work hard enough you could probably achieve this (eg get the COM application object pointer by some method and modify the cell that way, or set up a callback to modify the cell asynchronously), but you might have unpredictable results.

Reordering MFC control IDs automatically

I've got a pretty old MFC application that's been touched by many people over the years (most of them probably not even CS guys) and it follows, what I like to call the "anarchy design pattern."
Anyway, one of the dialogs has a series of 56 vertical sliders and check boxes. However, there are additional sliders and checkboxes on the dialog as shown below.
Now, the problem is that the additional sliders and checkboxes take on IDs that are in sequence with the slider/checkbox series of the dialog. My task is to add more sliders and checkboxes to the series (in the blank space in the Slider Control group box) Unfortunately, since IDC_SLIDER57 through IDC_SLIDER61 are already in the dialog (same goes for the checkboxes), existing code, such as the snippet below will break:
pVSlider = (CSliderCtrl *)GetDlgItem(IDC_SLIDER1+i);
Is there a better way to modify the resource file without doing it manually? I've seen a third party tool called ResOrg that looks like it'll help do what I want, but the software is a bit pricey, especially since I'll only use it once. I guess I can give the demo a try, but the limitations might restrict me.
FYI, I'm using Visual C++ 6.0 (yes...I know, don't laugh, it's being forced upon me).
Instead of writing:
pVSlider = (CSliderCtrl *)GetDlgItem(IDC_SLIDER1+i);
you could write:
pVSlider = (CSliderCtrl *)GetDlgItem(GetSliderID(i));
where GetSlider is a function that returns the id of slider number i.
GetSlider function
int GetSliderID(int nslider)
{
static int sliderids[] = {IDC_SLIDER1, IDC_SLIDER2, IDC_SLIDER3, .... IDC_SLIDERn};
ASSERT(nslider < _countof(sliderids));
return sliderids[nslider];
}
With this method the IDC_SLIDERn symbols dont need to have sequential values.

How to change row height in QTextTable

I'm writing the complicated rich text editor, derived from QTextEdit class. It must be able to insert, resize, and apply various formatting to embedded tables.
I found function for setup column widths (setColumnWidthConstraints).
But there is no one to change _rows_ heights.
Is there any way to achieve this?
Example code:
void CustomTextEdit::insertTable (int rows_cnt, int columns_cnt)
{
QTextCursor cursor = textCursor ();
QTextTableFormat table_format;
table_format.setCellPadding (5);
// TODO: This call just changed the frame border height, not table itself.
//table_format.setHeight (50);
// Setup columns widths - all is working perfectly.
QVector <QTextLength> col_widths;
for (int i = 0; i < columns_cnt; ++i)
col_widths << QTextLength (QTextLength::PercentageLength, 100.0 / columns_cnt);
table_format.setColumnWidthConstraints (col_widths);
// ...But there is no similar function as setRowHeighConstraints for rows!
// Insert our table with specified format settings
cursor.insertTable (rows_cnt, columns_cnt, table_format);
}
it seems that you can use the setHTML(QString) or insertHTML(QString) functions to insert a stylesheet.
When using this function with a style sheet, the style sheet will only
apply to the current block in the document. In order to apply a style
sheet throughout a document, use QTextDocument::setDefaultStyleSheet()
instead.
ref: http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libqt4/qtextedit.html#insertHtml
appart from using shims....according to http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libqt4/richtext-html-subset.html you can set the font declaration.
Qt seems to have targeted the CSS2.1 specification, which is as followed.. http://www.w3.org/TR/CSS2/fonts.html#propdef-font
have you tried specifying the font within the table row.
pass the following string using insertHTML, where this string is delcared as a QString
<style>
table > tr {font-size: normal normal 400 12px/24px serif;}
</style>
If you just want to make rows taller than their text height would require, you could try inserting a 0xN transparent image in the first cell of the row (or 1xN if Qt won't let you do zero-width).
It might also be possible to set the table cell's top padding with QTextTableCellFormat::setTopPadding() or maybe set the top margin with QTextBlockFormat::setTopMargin(). But both padding and margins are added to the text layout height AFAIK, so neither of them is very good for setting an absolute height.
Have you looked at Calligra? Its libs/kotext and libs/textlayout libraries implement a custom QAbstractTextDocumentLayout with much richer table support than QTextEdit.
Insert a stylesheet using this->document()->setDefaultStyleSheet("css goes here");
See http://qt-project.org/doc/qt-5.0/qtwidgets/qtextedit.html#document-prop
and http://qt-project.org/doc/qt-5.0/qtgui/qtextdocument.html#defaultStyleSheet-prop
(links go to Qt5 docs, but these functions are available in Qt4 also.)

What Uxtheme function I must use to get the default size of the minimize, Maximize and close buttons?

I'm using the DrawThemeBackground function to draw some system elements on a canvas, And I need draw the title buttons of a form, the only part that i missed is how i can get the default sizes of the title buttons. Exist any Uxtheme function to get that info?
Looks like this is more difficult then it sounds.
First there's GetThemeMetric or GetThemeInt. But you'll see a lot of references that these functions return a 0x8007490, some "element not found", when you try to retrieve properties of caption buttons.
Then there's GetThemePartSize. This one seems to work some. That is it works ok for instance for WP_CLOSEBUTTON, but it returns nonsense for instance for WP_MINBUTTON. I would not suggest this function's use anyway since it retrieves the default dimensions of the button. If the user has changed the title size for instance, you won't get correct values. Anyway, it could be called like this:
uses
uxtheme, themes;
...
var
Err: HRESULT;
Size: TSize;
begin
Err := GetThemePartSize(ThemeServices.Theme[teWindow], 0,
WP_CLOSEBUTTON, CBS_NORMAL, nil, TS_TRUE, Size);
I have no idea what the former two functions would return if they worked (the dimensions of buttons for current title bar size or the default title bar size).
The only possible way to get an accurate result seems to be to use the WM_GETTITLEBARINFOEX message. But there's a drawback; it works only for Vista and up. You may need to define the message and the struct it uses depending on the Delphi version you use (D2007 here).
const
CCHILDREN_TITLEBAR = 5;
WM_GETTITLEBARINFOEX = $033F;
type
tagTITLEBARINFOEX = record
cbSize: DWORD;
rcTitleBar: TRect;
rgstate: array[0..CCHILDREN_TITLEBAR] of DWORD;
rgrect: array [0..CCHILDREN_TITLEBAR] of TRect;
end;
TITLEBARINFOEX = tagTITLEBARINFOEX;
TTitleBarInfoEx = tagTITLEBARINFOEX;
PTitleBarInfoEx = ^TTitleBarInfoEx;
...
var
TitleInfo: TTitleBarInfoEx;
begin
SendMessage(Handle, WM_GETTITLEBARINFOEX, 0, NativeInt(#TitleInfo));
Then, you can get the size for the close button from the rect TitleInfo.rgrect[5]. See "TITLEBARINFOEX structure" for details. Notice the values are in screen coordinates.
If you need to support XP and/or below, I suggest you to use the good old GetSystemMetrics(SM_CXSIZE) and GetSystemMetrics(SM_CYSIZE) ("The width of a button in a window caption or title bar, in pixels"). You'd need to workout some approximations depending on if themes are enabled, if aero is enabled etc..
I think SystemParametersInfo with SPI_GETNONCLIENTMETRICS is what you're looking for. I guess the minimize and maximize buttons use NONCLIENTMETRICS.iSmCaptionWidth while close uses iCaptionWidth to determine width.

MFC: Displaying a tabulated display of text items

This should be simple it seems but I can't quite get it to work. I want a control (I guess CListBox or CListCtrl) which displays text strings in a nice tabulated way.
As items are added, they should be added along a row until that row is full, and then start a new row. Like typing in your wordprocessor - when the line is full, items start being added to the next line, and the control can scroll vertically.
What I get when trying with a list-mode CListCtrl is a single row which just keeps growing, with a horizontal scroll bar. I can't see a way to change that, there must be one?
You probably need a list control wth LVS_REPORT. If you expect the user to add items interactively using a keyboard, you probably need a data grid, not a list. Adding editing to list control subitems is not easy, and it would be easier to start from CWnd. Search "MFC Data Grid" to find some open source class libraries that implemented the feature.
If you can afford adding /clr to your program, you can try the data grid classes in Windows Forms using MFC's Windows Form hosting support. You will find a lot more programming resources on data grid classes in Windows Forms than any other third-party MFC data grid class library.
If you use CRichEditCtrl you can set it to word-wrap, take a look at this snippet extracted from:
http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.ui/2004-03/0111.html
(I've derived my own QRichEditCtrl from the MFC CRichEditCtrl,
and here's the relevant code:)
void QRichEditCtrl::SetWordWrap(bool bWrap)
{
RECT r;
GetWindowRect(&r);
CDC * pDC = GetDC();
long lLineWidth = 9999999; // This is the non-wrap width
if (bWrap)
{
lLineWidth = ::MulDiv(pDC->GetDeviceCaps(PHYSICALWIDTH),
1440, pDC->GetDeviceCaps(LOGPIXELSX));
}
SetTargetDevice(*GetDC(), lLineWidth);
}