So far am able to create the following controls on winapi c++: Button, Checkbox, Groupbox, Listbox,Edit Text,Label,Status Bar,Shapes, Lines
However having come from VB 6 which we did in College I am having a problem creating controls like: Picture Box, Image box, which i used extensively in vb 6 to arrange other controls. In a picture box you could actually stick it to the top, left or bottom then drop controls on it. Afterwards i leave some space where mdi windows can show when opened.
There is no PictureBox equivalent in WinAPI. Things are more involved than that. You need to load the picture yourself using the LoadImage function, create a memory device context using a CreateCompatibleDC function and BitBlt it where appropriate. Do the painting inside the WM_PAINT message handling block.
Related
I have seen several tools adding a custom button and/or drawing on the title bar of all windows of all applications in Windows. How is that done?
Extra points for an example in Delphi.
EDIT:
I found something for dotNET that does this:
http://www.thecodeking.co.uk/2007/09/adding-caption-buttons-to-non-client.html#.VdmioEDenqQ
How I see this job:
First of all we should be able to paint this button on the our own window caption. This procedure will be used later
This part of the program enumerates the active and visible windows
This part of the program using injection attach our dll to enumerated windows
From injected dll we can draw the button on the window caption
Inside this dll we should process the click on the button
We should have mechanism to send result to our main program
I haven't done this, so the following is what I would investigate if I were to try:
For each application / each top-level window:
Create a floating window and position it over the title bar wherever you want it to sit. Set up the parent / child relationship, but this window is part of your own process. (There are occasionally problems parenting a window from one process to one from another process, but try. I'd avoid injecting into other processes if possible.)
You can investigate the window flags to see if the window has a title bar (ie if you should add a button) via GetWindowLong with GWL_STYLE looking for WS_CAPTION. The same call will also let you see the type of caption / frame, which you can combine with GetSystemMetrics with, eg, SM_CYDLGFRAME to figure out the right size for your button on this specific window's title bar.
This window is now your button: paint, handle clicks etc as appropriate.
Make it a non-focusable window so that clicks to it don't take focus away from the window is is on the title bar of. You don't want clicking it to make the title bar change colour, for example. Do this by setting the WS_EX_NOACTIVATE window flag, something like: SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) orWS_EX_NOACTIVATE).
The main problem is to keep it positioned correctly when the window moves, is resized, etc. To do this, install a hook for the system move events. You can also hook minimize and restore via EVENT_SYSTEM_MINIMIZESTART and EVENT_SYSTEM_MINIMIZEEND. This will allow you to keep track of all windows moving around onscreen, such that you can adjust the button-window position if necessary.
That gives you a window which you can paint as a button (and respond to clicks etc), that visually is "attached" to other windows so it stays in the same place as the user drags the title bar, minimizes or maximises the app, etc, and that is in your own process without cross-process problems.
I am trying to capture windows hidden behind my application. I am using windows 7 and VC++. I have tried printwindow() function which draws the both non-client and client area of hidden window, but captured window in the device context doesn't show desktop composition effects(aero effects). Instead it shows the captured window with windows 7 basic theme.
I have also tried with GetWindowDC() to retrive the DC of hidden window, and then Bitblt() it to memory DC but the captured window doesn't show non-client area (caption, close button, minimize button etc) correctly.
Anybody faced this issue?
Please help.
Click the link below. It leads to a MSDN site that lists all the existing Windows Functions ever of all history since Windows 95 up to Windows 8 (from period where Microsoft started Windows until present). It shows old windows functions of first Windows and new windows functions added for the new windows.
http://msdn.microsoft.com/en-us/library/windows/desktop/ff468919(v=vs.85).aspx
Anyway follow this site.
You will see the name of each function as a link.
Click any of them that you are interested.
Each link there leads to another MSDN site that explains all the basics knowledge that you must know about the function before using it, that you want to learn more. What that function does, its purpose, all its parameters and how to use each one, all their flags, all parameters types, return value and at last remarks section that shed more light and sometimes gives tips about the selected function.
Of course, you don't have to read all of them. Find in the list only the necessary functions to fit your needs. The functions that will solve your problem and answer your question that you posted.
By the way, I read your post, and I think that I found in the list the necessary functions that will do what you want to do, I will list them below, and say in one sentence what each does for what you need:
AnimateWindow - Enables you to produce special effects when showing or hiding windows. There are four types of animation: roll, slide, collapse or expand, and alpha-blended fade.
FlashWindow - Flashes the specified window one time. It does not change the active state of the window.
FlashWindowEx - Flashes the specified window specified number of times. It does not change the active state of the window.
Use these functions to achieve the aero effects that you want.
SetWindowPos - Changes the size, position, and Z order of a child, pop-up, or top-level window. These windows are ordered according to their appearance on the screen. The topmost window receives the highest rank and is the first window in the Z order.
Use this function to show the hidden windows on the top side (above all other windows) and on the screen front of you. The operating system will automatically draw the both non-client and client area of these windows without using any gdi, draw and paint functions yourself.
If you want these windows to return back to their previous state (where they were hidden), then save their state with GetWindowPlacement function and later call SetWindowPlacement to bring them back to their hidden state. You can try GetWindowRect and SetWindowPos instead to achieve the same goal.
I also think that you will be interested in GetWindowTheme and SetWindowTheme functions and all the draw theme functions (BackgroundEx, Edge, Icon, Text, TextEx).
There are more theme functions. Find in msdn and in other sites on the web.
My application is screenshot maker. User needs to select screen area to make a screenshot. I use Win32 API with PureBasic, but it doesn't matter, all is similar with C++.
When user runs application, the semitransparent borderless form is shown on full screen to hook mouse over all other windows. On mouse down event selection is started and I apply XORed region to the form to cut a hole in it with size of current selection.
I create and apply a new region on every mousemove event:
rgn1 = CreateRectRgn_(0,0,DWidth,DHeight) ; full size of desktop
rgn2 = CreateRectRgn_(sx, sy, ex, ey) ; current selection points
CombineRgn_(rgn1, rgn1, rgn2, #RGN_XOR)
SetWindowRgn_(WindowID(0), rgn1, #True); apply region
It works well on my computer with Windows XP, but works buggy on other computer with Vista. I think it is wrong when I create the new region object on every mouse move. Maybe I need to create it once and then to resize? Can anybody explain how to do this right? Examples on C++ are ok.
In the beginning you create region, using CreateRectRgn (like in your code).
Then it's enough to call SetRectRgn function for updating region bounds
I'm using MFC (yes must be MFC and no I can't interop with .Net) to create a CFrameWnd.
My goal is to create a CFrameWnd containing a CFormView which is based on a Dialog Template that resembles something like:
I have got the frame and view to display, and I have an Edit control on there. Now what I want is to have a CToolbar aligned to the top of the Edit Text control but not docked to the top frame.
Ideally I would like to have a child frame/view that I can dynamically add in place of the Statement Group. That way I could just dock the toolbar as normal.
The thing that I find odd is that I could easily achieve this if I had a splitter in there by using the CreateView function. I really don't want to have a splitter and feel there ought to be another way.
In summary, these are the question I need help with:
Q1 - How can I have a CFrameWnd within a CView (like what CSplitter::CreateView does)?
Q2 - How can I position a toolbar within a CView without docking or floating it within another frame (I'm more than willing to resize, position it manually if only I knew how)?
Now I really appreciate how easy things are in .Net.
I wouldn't recommend sticking a CFrameWnd within a CView. You'll be fighting MFC all the way, basically living in a world of ASSERTs as the internal functionality such as message routing assumes that Frames don't live in views.
Instead just use a CWnd instead of the CFrameWnd and in the 'Create' method manually create the toolbar and the edit ctrl and size and position them yourself (create a AdjustLayout method that uses CMFCToolbar::CalcFixedLayout to adjust the position of your other components).
A great example of this is in the Visual Studio sample app PropertiesViewBar.cpp:
http://msdn.microsoft.com/en-us/library/bb983983(v=vs.90).aspx
Note: You might need to override OnCmdMsg to extend the message routing to the internal controls.
I'm developing an interactive MFC application which displays a 3D object using my own algorithm, essentially using MFC as a framework, but using lots of pDC->Polygon(), pDC->Rectangle(), pDC->DrawText(), etc. calls.
The UI has numerous clickable areas which all work well. However, the onscreen controls for rotating, spinning, etc. the 3D image motivate users to double click, triple click, and beyond.
I'm 99% positive that CWnd::OnLButtonDown() is not called until Windows (or whatever) has decided the operation is not a double click, or when double clicked, but only once. That is a series of clicks results in a notification every second click. The user experience is stuttered rotation. The temporary workaround is to have users move the mouse slightly between clicks—It solves the problem, but is rather unfriendly.
The application does no double click event hooking. Maybe there's a way to go further to disable potential double click processing? Or maybe there is a lower-level way to capture the mouse button down?
I think you have it backwards - the first click gets through as a WM_LBUTTONDOWN, the second one gets turned into a double-click.
To prevent a window from generating WM_LBUTTONDBLCLK messages, remove the CS_DBLCLKS style from the window.
This is all explained in the WM_LBUTTONDBLCLK documentation.
Edit: I misspoke, CS_DBLCLKS is a class style, not a window style. I don't think you can remove it, you have to create a new window class that doesn't include it. It's provided by MFC - see this page http://msdn.microsoft.com/en-us/library/a77269ff(VS.80).aspx.
Just to add an answer, this method worked for me:
WORD dwStyle = GetClassLongPtr(handle, GCL_STYLE);
dwStyle &= ~CS_DBLCLKS;
SetClassLongPtr(handle, GCL_STYLE, dwStyle);
You can use these functions to edit a WNDCLASSEX style structure for an specific window removing the double click event and correcting the single click behavior.
GetClassLongPtr
SetClassLongPtr