Specifying the width of a TaskDialog - winapi

I'm using a task dialog via the TaskDialogIndirect function.
Everything works as expected except that the width of the dialog is exactly twice of what I specified in the cxWidth field of the TASKDIALOGCONFIG structure.
Relevant code:
TASKDIALOGCONFIG tdc;
ZeroMemory(&tdc, sizeof(tdc));
tdc.cbSize = sizeof(TASKDIALOGCONFIG);
tdc.hwndParent = hwndParent;
tdc.hInstance = NULL;
tdc.pszWindowTitle = L"Title";
tdc.pszMainInstruction = L"Foo";
tdc.pszContent = L"Bar";
tdc.dwFlags = TDF_POSITION_RELATIVE_TO_WINDOW;
tdc.cxWidth = 150;
int result;
HRESULT hr = TaskDialogIndirect(&tdc, &result, NULL, NULL);
The documentation says that the cxWidth is the width in dialog units.
With the code above the width of the dialog is 300 pixels instead of 150 which means that one horizontal dialog unit is 2 which seems really small.
If I want to specify the width of the task dialog explicitely, how should I proceed? Is suppose I cannot rely on the fact that one horizontal dialog unit is always 2 in this case.

Related

can't change the height of status bar control in a property page in win32

I have a windows application in which I am trying to create a status bar at the bottom of a PropertyPage. I have added a member variable of type CStatusBarCtrl named m_StatBar in the derived propertypage class.
Here is the code in the OnInitDialog of the PropertyPage
enter code here
int nTotWide; // total width of status bar
CRect rect3;
this->GetWindowRect(&rect3);
rect3.top = rect3.bottom - 70;
int m_bRvStatOk = m_StatBar.Create(WS_CHILD | WS_BORDER | WS_VISIBLE, rect3, this,IDC_STATUSBAR);
if (m_bRvStatOk == NULL)
{
AfxMessageBox("Status Bar not created!", NULL, MB_OK);
}
// get size of window, use to configure the status
// bar with four separate parts
nTotWide = rect3.right - rect3.left;
//
// Make each part 1/4 of the total width of the window.
//
m_Widths[0] = nTotWide / 4;
m_Widths[1] = nTotWide / 2;
m_Widths[2] = nTotWide - m_Widths[0];
m_Widths[3] = -1;
m_StatBar.SetMinHeight(70);
m_StatBar.SetParts(4, m_Widths);
m_StatBar.SetText("TEXT WITH BORDER.", 0, 0);
m_StatBar.SetText("TEXT WITHOUT BORDER.", 1, SBT_NOBORDERS);
m_StatBar.SetText("TEXT POPUP.", 2, SBT_POPOUT);
I am not able to change the height of the status bar.
appreciate any help on the same.
You cannot set the height of a status bar. However, you can request a minimum size by sending an SB_SETMINHEIGHT message to the control (which is what the CStatusBarCtrl::SetMinHeight implementation does).
This is not enough for the system to pick up the requested minimum height, though. While the MFC documentation doesn't provide any help or hint, the SB_SETMINHEIGHT documentation has the following remark:
An application must send the WM_SIZE message to the status window to redraw the window. The wParam and lParam parameters of the WM_SIZE message should be set to zero.
This translates to the following MFC implementation:
m_StatBar.SetMinHeight(70);
m_StatBar.SendMessage(WM_SIZE); // wParam and lParam have default arguments set to 0

Getting the exact edit box dimensions for the given text

I need to be able to determine the size of the edit box according to the text I have, and a maximum width.
There are similar questions and answers, which suggest GetTextExtentPoint32 or DrawTextEx.
GetTextExtentPoint32 doesn't support multiline edit controls, so it doesn't fit.
DrawTextEx kind of works, but sometimes the edit box turns out to be larger than necessary, and, what's worse, sometimes it's too small.
Then there's EM_GETRECT and EM_GETMARGINS. I'm not sure whether I should use one of them, or maybe both.
What is the most accurate method for calculating the size? This stuff is more complicated then it should be... and I prefer not to resort to reading the source code of Wine or ReactOS.
Thanks.
Edit
Here's my code and a concrete example:
bool AutoSizeEditControl(CEdit window, LPCTSTR lpszString, int *pnWidth, int *pnHeight, int nMaxWidth = INT_MAX)
{
CFontHandle pEdtFont = window.GetFont();
if(!pEdtFont)
return false;
CClientDC oDC{ window };
CFontHandle pOldFont = oDC.SelectFont(pEdtFont);
CRect rc{ 0, 0, nMaxWidth, 0 };
oDC.DrawTextEx((LPTSTR)lpszString, -1, &rc, DT_CALCRECT | DT_EDITCONTROL | DT_WORDBREAK);
oDC.SelectFont(pOldFont);
::AdjustWindowRectEx(&rc, window.GetStyle(), (!(window.GetStyle() & WS_CHILD) && (window.GetMenu() != NULL)), window.GetExStyle());
UINT nLeftMargin, nRightMargin;
window.GetMargins(nLeftMargin, nRightMargin);
if(pnWidth)
*pnWidth = rc.Width() + nLeftMargin + nRightMargin;
if(pnHeight)
*pnHeight = rc.Height();
return true;
}
I call it with nMaxWidth = 143 and the following text (below), and get nHeight = 153, nWidth = 95. But the numbers are too small for the text to fit, on both axes.
The text (two lines):
Shopping
https://encrypted.google.com/search?q=winapi+resize+edit+control+to+text+size&source=lnms&tbm=shop&sa=X&ved=0ahUKEwiMyNaWxZjLAhUiLZoKHQcoDqUQ_AUICigE
Edit 2
I found out that the word wrapping algorithm of DrawTextEx and of the exit control are different. For example, the edit control wraps on ?, DrawTextEx doesn't. What can be done about it?

Out of memory error when reloading activity several times

I am developping an app that has a main activity showing the app title (two animated imageviews overlayed), two animated pictures, also overlayed, and three buttons. This activity also has a background image, which is the same that is used by the other activities.
The app flows from one activity to another and, eventually, this main activity is launched again (with the FLAG_ACTIVITY_CLEAR_TOP). Everything works fine but, after reloading it several times, an Out Of Memory error happens on my Android 2.1 device.
At first, I had all the images in the drawable folder and the problem appeared after reaching the main activity 5 times. Then, I adjusted the bitmap sizes and put them in the approppriate folders depending on the density and the problem appeared after reaching the main activity 14 times. Now, I just removed the background image for test purposes and the Out Of Memory appears after more than 20 re-launches.
Also, if I press the Home button and then switch back to my app, the problem seems not to appear until much later.
Moreover, I tested the app in a Nexus 5 and the Out Of Memory never happens.
So... is that a problem with my phone? with Android 2.1?
Thanks!
[EDIT]
I think that I have located the problem but, still, strange behavior.
For example, at one point, I need to recreate the activity. As the "recreate" method is not available for my min API level (7), I do it as follows:
Intent refresh = new Intent(getActivity(), getActivity().getClass());
refresh.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(refresh);
Which, I think, is correct. I release the onClickListeners and clear the animations in onStop(). However, if I put a breakpoint in onStop(), it is not called when I expect it to happen. Sometimes it is called as soon as the activity is recreated but sometimes it is called several seconds later.
However, if I press the Home button, onStop is properly called and when I switch back to the application everything works fine.
The easiest solution is to add in manifest under application tag
android:largeHeap="true"
But this is won't solve your problem, just delay it to a few more rounds
This link will help you to analyze your application and see what cause this:
http://blogs.innovationm.com/android-out-of-memory-error-causes-solution-and-best-practices/
My Guess this is related to images because i had this issue also..
The android official link to this problem is:
http://developer.android.com/training/displaying-bitmaps/index.html
This the link that helped me.. Try it out
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Hope that helps
check this outLoading Large Bitmaps Efficiently
Read Bitmap Dimensions and Type
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Load a Scaled Down Version into Memory
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
imageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

Creating X11 window to span multiple displays

I'm having the exact problem described here. How to make X11 window span multiple monitors
I have six monitors and am trying to create a window larger than the size of one of the monitors. It keeps getting resized by the window manager.
Apologize if I should post within that thread, the etiquette is not clear to me.
Anhow, I do the following in my code:
/* Pass some information along to the window manager to size the window */
sizeHints.flags = USSize; // | PMinSize;
sizeHints.width = sizeHints.base_width = width;
sizeHints.height = sizeHints.base_height = height;
// sizeHints.min_width = width;
// sizeHints.min_height = height;
// sizeHints.max_width = mScreenWidth;
// sizeHints.max_height = mScreenHeight;
if (geometry->x != DONT_CARE && geometry->y != DONT_CARE) {
sizeHints.x = geometry->x;
sizeHints.y = geometry->y;
sizeHints.flags |= USPosition;
}
XSetNormalHints(mDisplay, mWindow, &sizeHints);
SetTitle(suggestedName);
XSetStandardProperties(mDisplay, mWindow,
suggestedName.toAscii(), suggestedName.toAscii(),
None, (char **)NULL, 0, &sizeHints);
/* Bring it up; then wait for it to actually get here. */
XMapWindow(mDisplay, mWindow);
The problem I'm having is that if I set min_width and min_height, the user cannot resize the window, which is not what I want. But if I don't, then when I do any X11 call later, such as
XGetWindowAttributes(mDisplay, mWindow, &win_attributes);
the window manager resizes my window to fit into one monitor instead of being larger than the monitor. I cannot just get a window of the desired size for some reason. Note that WidthOfScreen and HeightOfScreen give me the combined width and height of all monitors as expected.
Can anyone help? I hope I'm explaining myself clearly enough.

Animate Button size, then revert to null

I am trying to create an animation to make it look like a button turns over and the back shows. So what I was trying to do is:
1- Show a button with BackgroundColor x. (The button now has a Width of null, the property ActualWidth does have a value.)
2- Create a double animation that changes the width of the button to zero.
DoubleAnimation widthAnimation = new DoubleAnimation();
widthAnimation.From = this.ActualWidth;
widthAnimation.To = 0;
widthAnimation.SpeedRatio = 3;
widthAnimation.Duration = TimeSpan.FromMilliseconds(800);
3- Change the BackgroundColor of the button.
ColorAnimation colorAnimation = new ColorAnimation();
colorAnimation.From = State ? _xColor : _yColor;
colorAnimation.To = State ? _yColor : _xColor;
colorAnimation.BeginTime = TimeSpan.FromMilliseconds(400);
colorAnimation.Duration = TimeSpan.Zero;
4- Change the width back to it's original value.
widthAnimation.AutoReverse = true;
The problem is when the animation runs twice the animation reads this.ActualWidth while animating, which causes it to fail to the original width. How can I solve this? I would like to set the Width back to null again, but it seems impossible to me.
You'd better use xaml style and template to "declare" what you want and let WPF/Silverlight take care of all.
If you try to do the same thing by code you can do it but you need to know what the framework does behind the scenes.
Basically you can set
- Style to define the values of some properties of the control
- DataTemplate to define the visual representation of the control's content
- ControlTemplate to define the appearance of the control
Each of those can have Triggers
- Property Triggers
to set properties or starts actions, such as an animation
when a property value changes or when an event is raised;
EventTriggers and Storyboards
to start a set of actions based on the occurrence of an event
If you like to learn about XAML Style and Template,
take a look at http://msdn.microsoft.com/en-us/library/ms745683.aspx
Spend a day to learn and save many hours (or days) of try and error and frustration!
To go right to the point, in your case I think you should use a Storyboard.
See http://msdn.microsoft.com/en-us/library/ms742868.aspx
where you can find also the code equivalent of XAML examples
I came to the idea to targetting the MaxWidth instead of the actual Width. I now use a KeyFrameCollection which sets the MaxWidth to int.MaxValue at the start (so also at the end when using autoreverse).
It will work fine untill there will be phones with a resolution bigger than the max int value.
The code:
DoubleAnimationUsingKeyFrames widthAnimation = new DoubleAnimationUsingKeyFrames();
widthAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame()
{
KeyTime = TimeSpan.Zero,
Value = int.MaxValue,
});
widthAnimation.KeyFrames.Add(new LinearDoubleKeyFrame()
{
KeyTime = TimeSpan.FromMilliseconds(1),
Value = ActualWidth,
});
widthAnimation.KeyFrames.Add(new LinearDoubleKeyFrame()
{
KeyTime = TimeSpan.FromMilliseconds(400),
Value = 0,
});
widthAnimation.Duration = TimeSpan.FromMilliseconds(400);
widthAnimation.AutoReverse = true;

Resources