MFC How to create a context menu with scrolling capability - visual-c++

I need to create a context menu with scrolling capability because I need to insert a lot of file names on it, just like Visual Studio 2010's open files context menu.
Anybody has any idea on how to implement this with MFC?

Windows menu supports scrolling if you have more items than fit into the visible part. You can verify it by inserting a couple hundred items into your menu.
I guess the question should be: how to limit the vertical size of the menu (as it would otherwise extend to the height of your screen). Here is an example:
CMenu menu;
menu.CreatePopupMenu();
CString s;
for (int i = 1; i < 100; ++i)
{
s.Format(L"Item %.3d", i);
menu.AppendMenu(MF_STRING, i, s);
}
MENUINFO mi = { sizeof(MENUINFO) };
mi.fMask = MIM_MAXHEIGHT;
mi.cyMax = 400;
menu.SetMenuInfo(&mi);
menu.TrackPopupMenu(TPM_RETURNCMD, 100, 100, this);

Related

Moving windows in ncurses

I've read window(3NCURSES) man page, but I can't fully understand what mvwin() function actually does and what happens to its subwindows.
The code below creates a window with a title "Window" and a border, it also creates a subwindow that is used for printing y,x position without corrupting parent window border. It then moves the parent window to a new location, but the result is not what I expected:
After the window is moved, the outline of the windows border + text is not automatically erased at the old location.
After the move, writing text to a subwindow, outputs it at the old and new location.
After the move, parent window has new y,x coordinates, but subwindow still shows old coordinates.
I don't have a lot of experience with ncurses, and maybe I'm missing something, but this behaviour is completely illogical. If I have to manually erase windows at old location and manually move all subwindows, then this negates the benefit of using ncurses in the first place. I was expecting ncurses to automatically handle these low-level details.
My understanding of subwindows was that they are used to partition one large window into smaller non-overlapping areas. So when the parent window is moved or refreshed, all its subwindows should be moved or refreshed automatically. Is this correct?
#include <assert.h>
#include <ncurses.h>
#include <unistd.h>
int main()
{
WINDOW *win, *swin;
int lines, cols, y, x;
initscr();
keypad(stdscr, TRUE);
noecho();
// Create window
lines = 10; cols = 40;
y = 5; x = 5;
win = newwin(lines, cols, y, x);
assert(win != NULL);
// Create window border
box(win, 0, 0);
mvwprintw(win, 0, 2, " Window ");
// Create subwindow
swin = subwin(win, lines-2, cols-2, y+1, x+1);
assert(swin != NULL);
// Print window and subwindow y,x
mvwprintw(swin, 0, 0, "win y,x=%d,%d swin y,x=%d,%d\n",
getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));
// Refresh
wnoutrefresh(stdscr);
wnoutrefresh(win);
wnoutrefresh(swin);
doupdate();
sleep(2);
// Move window
y = 20; x = 40;
mvwin(win, y, x);
mvwprintw(swin, 0, 0, "win y,x=%d,%d swin y,x=%d,%d\n",
getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));
// Refresh
wnoutrefresh(stdscr);
wnoutrefresh(win);
wnoutrefresh(swin);
doupdate();
wgetch(swin);
endwin();
return 0;
}
Apparently not: a quick check with Solaris 10 gives the same behavior. You might find some scenario where ncurses differs unintentionally, but this is not one of those. The FAQ makes this point about compatibility:
extensions (deviations from SVr4 curses) are allowed only if they do not modify the documented/observed behavior of the API.
The Solaris manual page does not make this clear, since the only mention of subwindows is in regard to moving them:
The mvwin() routine moves the window so that the upper left-hand corner is at position (x, y). If the move would cause the window to be off the screen, it is an error and the window is not moved. Moving subwindows is allowed, but should be avoided.
The Solaris source code tells the story for that: it does nothing with subwindows. Some retesting a while back (early 2006) in response to a user's comment about differences pointed out that ncurses was incorrectly attempting to copy subwindows. That part is ifdef'd out (since it's too interesting to just delete). Since there's not much left for mvwin to do, the actual code is fairly similar.
X/Open's description of mvwin is too brief and vague to be of any use.

Resize a window to exceed the resolution boundary under X

I know users can move a window around and make it partially outside of the resolution boundary under X window system. Is it possible to change the size to achieve the same result either programmatically or manually?
Here is my experimental code, but it doesn't work.
Window w;
int revert_to;
XGetInputFocus(m_display, &w, &revert_to);
if (w == None) {
printf("can't get focused window");
}
else {
Window top = get_top_window(m_display, w);
XWindowAttributes xwa;
XGetWindowAttributes(m_display, top, &xwa);
XClassHint xch;
XGetClassHint(m_display, top, &xch);
printf("focused window name: %s pos: %d, %d size: %d, %d", xch.res_class, xwa.x, xwa.y, xwa.width, xwa.height);
XResizeWindow(m_display, top, 900, 1900);
}
get_top_window is some codes from internet
Window get_top_window(Display* d, Window start) {
Window w = start;
Window parent = start;
Window root = None;
Window *children;
unsigned int nchildren;
Status s;
printf("getting top window ... \n");
while (parent != root) {
w = parent;
s = XQueryTree(d, w, &root, &parent, &children, &nchildren); // see man
if (s)
XFree(children);
if(xerror) {
printf("fail\n");
exit(1);
}
printf(" get parent (window: %d)\n", (int)w);
}
printf("success (window: %d)\n", (int)w);
return w;
}
Take terminal as an example, this code could change the inner window but the outline window with titlebar is not affected. is this because the outline window is generated by window manager? And how could I resize it as one unit?
Apart from that, I also can't resize the window out of the resolution boundary. Any solution?
Edit: I use compiz window manager and there is no corresponding setting in Compiz configuration settings manager.
Edit: With the settings in this link, I'm able to resize a window out of the screen resolution by using mouse middle button click and drag trick. But programmatical method is still not working.

Align DialogBar in Frame and set its width

I'm working on an MFC project which was transferred to me.
It's basic layout (main frame derived from CFrameWnd) is shown in this sketch:
The CommandBar and the ControlBar, both derived from CDialogBar, were created using WS_CHILD | CBRS_ALIGN_RIGHT as style.
This is fine for the alignment. But I would like to define the widths of these two elements and cannot find a way to set it.
When I tried to EnableDocking for the dialog bars, I couldn't manage to resolve the assertions. Also I'm not sure if this is what I am looking for.
Overriding CalcDynamicLayout and returning the calculated size is what I was looking for.
Example:
CSize CommandBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
CSize size;
CRect parentRect;
if (GetParent())
GetParent()->GetClientRect(&parentRect);
size.cy = parentRect.Height();
size.cx = (int)(abs(parentRect.Width() - parentRect.Height() + GetSystemMetrics(SM_CYMENUSIZE)) * 0.5);
return size;
}

j2me: using custom fonts(bitmap) performance

I want to use custom fonts in my j2me application. so I created a png file contains all needed glyph and an array of glyphs width and another for glyphs offset in PNG file.
Now, I want to render a text in my app using above font within a gameCanvas class. but when I use the following code, rendering text in real device is very slow.
Note: the text is coded(for some purposes) to bytes and stored in this.text variable. 242=[space],241=[\n] and 243=[\r].
int textIndex = 0;
while(textIndex < this.text.length)
{
int index = this.text[textIndex] & 0xFF;
if(index > 243)
{
continue;
}
else if(index == 242) lineLeft += 3;
else if(index == 241 || index == 243)
{
top += font.getHeight();
lineLeft = 0;
continue;
}
else
{
lineLeft += widths[index];
if(lineLeft <= getWidth())
lineLeft = 0;
int left = starts[index];
int charWidth = widths[index];
try{
bg.drawRegion(font, left, 0, charWidth, font.getHeight(), 0, lineLeft, top, Graphics.LEFT|Graphics.TOP);
}catch(Exception ee)
{
}
}
textIndex++;
}
Can anyone help me to improve performance and speed in my code?
At end sorry for my bad English and thanks in advanced.:)
Edit: I changed line
bg.drawRegion(font, left, 0, charWidth, font.getHeight(), 0, lineLeft, top, Graphics.LEFT|Graphics.TOP);
To:
bg.clipRect(left, top, charWidth, font.getHeight());
bg.drawImage(font, lineLeft - left, top,0)
bg.setClip(0, 0, getWidth(), getHeight());
but there was no difference in speed!!
any help please!!
Can anyone plz help me to improve my app?
text will appear after 2-3 seconds in real device by this code, I want reduce this time to milliseconds. this is very important for me.
Can I use threads? If yes, How?
I can't sure why your code's performance is not good in real device.
But, how about refer some well known open source J2ME libraries to check it's text drawing implementation for example, LWUIT.
http://java.net/projects/lwuit/sources/svn/content/LWUIT_1_5/UI/src/com/sun/lwuit/CustomFont.java?rev=1628
You can find from the above link it's font drawing implementation. It uses drawImage rather than drawRegion.
I would advice you to look into this library. The implementation is quite good and makes use of industry standard design patters ( Flyweight pattern, predominantly) and robust.

C# override WndProc in Control level to detect

I have overridden WndProc in UserControl level to detect MouseDown, MouseUp, and MouseMove to any Control added in that UserControl.
protected override void WndProc(ref Message m)
{
Point mouseLoc = new Point();
switch (m.Msg)
{
case WM_LBUTTONDOWN:
System.Diagnostics.Debug.WriteLine("mouse down");
//this.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, mouseLoc.X, mouseLoc.Y, 0));
break;
case WM_LBUTTONUP:
System.Diagnostics.Debug.WriteLine("mouse up");
//this.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, mouseLoc.X,mouseLoc.Y, 0));
break;
case WM_MOUSEMOVE:
int lParam = m.LParam.ToInt32();
//mouseLoc.X = lParam & 0xFFFF;
//mouseLoc.Y = (int)(lParam & 0xFFFF0000 >> 16);
mouseLoc.X = (Int16)m.LParam;
mouseLoc.Y = (Int16)((int)m.LParam >> 16);
System.Diagnostics.Debug.WriteLine("mouse move: " + mouseLoc.X + ", " + mouseLoc.Y);
//this.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, mouseLoc.X,mouseLoc.Y, 0));
break;
}
base.WndProc(ref m);
}
MouseMove, Down, and Up are working when the mouse pointer is in UserControl but when the mouse pointer is on other control (inside my UserControl) it doesn't work.
Am I doing something wrong?
Currently developing a flick and scroll control.
This is how windows works - each control in winforms is a window, and mouse messages go to the window they are over. If you need to get the mouse input from other windows you need to cooperate them somehow.
Having said all of that, if all you want is a flick and scroll control, you should consider looking at the WM_GESTURE APIs - that is what they are for, and they will allow you to implement flick and scroll without any cooperation from your child windows.
You're not doing anything "wrong", but Windows is simply sending the message to the correct control. It does not send the message to all the enclosing controls as well.
For key events there is the the Form.KeyPreview property, which allows the form to receive the events as well, but I'm not aware of anything similar for mouse events.

Resources