The MASM Forum

General => The Workshop => Topic started by: NoCforMe on February 05, 2022, 01:43:15 PM

Title: How to create a window with panes
Post by: NoCforMe on February 05, 2022, 01:43:15 PM
So let's say a guy wants to create an application with a window containing several panes, something like OllyDbg, where the panes are linked together and mutually resize and all.

How would he do that? Is this something that requires Visual Studio? MFC? Can ResEd create something like this? Is it possible to "roll your own" (even though I'm sure that would be more work)? Perplexed here.
Title: Re: How to create a window with panes
Post by: hutch-- on February 05, 2022, 04:58:28 PM
The magic secret is the API MoveWindow().
Title: Re: How to create a window with panes
Post by: NoCforMe on February 05, 2022, 05:28:12 PM
Quote from: hutch-- on February 05, 2022, 04:58:28 PM
The magic secret is the API MoveWindow().
You mean the function MoveWindow() in the Win32 API.  :dazzled:

But what about those nice seamless shared borders: how do you get those? Plus those dividers that you can grab and drag; those aren't normal window borders.
Title: Re: How to create a window with panes
Post by: hutch-- on February 05, 2022, 05:31:50 PM
> You mean the function MoveWindow() in the Win32 API

No, I meant what I said, the API MoveWindow().
Title: Re: How to create a window with panes
Post by: NoCforMe on February 05, 2022, 05:35:35 PM
OK, but how do you get those shared borders and dividers? Those don't just happen when you put windows next to each other.
Title: Re: How to create a window with panes
Post by: hutch-- on February 05, 2022, 05:41:10 PM
GetClientRect() and/or GetWindowRect() for coordinates, then use MoveWindow() to position each child window to where you want it.

If you need to use GetWindowRect() which produces screen rather than client coordinates, you use either ScreenToClient() or the reverse ClientToScreen() to get the coordinates you need.

There is no easy way to do what you want.
Title: Re: How to create a window with panes
Post by: TimoVJL on February 05, 2022, 06:35:22 PM
Olly seems to be a MDI application.
Inside window don't have to be real dividers, an illusion is enough, as frame window can act as divider for child windows.
Only GetClientRect() and MoveWindow() are needed with some global X and Y variables.
Client windows can have their own borders / shadows.
Title: Re: How to create a window with panes
Post by: jj2007 on February 05, 2022, 07:06:52 PM
Hutch is right, there is no magic API that does the job for you - it's all MoveWindow. Probably, that is: Olly does not use standard controls. You should absolutely try WinID (https://dennisbabkin.com/winid/), it gives you a wealth of information about the controls used.
Title: Re: How to create a window with panes
Post by: NoCforMe on February 05, 2022, 08:34:01 PM
I use WinSpy, which I think does about the same thing, give you info about whatever window (control) you click over.
Title: Re: How to create a window with panes
Post by: TimoVJL on February 05, 2022, 08:51:15 PM
This silly program written in C have two panes.
http://masm32.com/board/index.php?topic=7483.msg81793#msg81793
With it, someone see a one way to do panes.
Title: Re: How to create a window with panes
Post by: HSE on February 05, 2022, 10:55:24 PM
There are several "mechanisms" that can be used to make those interfaces.
Most IDE programs use docking windows, but inside that windows they sometimes use the others mechanisms  :rolleyes:

Later I remembered that Zale don't like docking windows, then PB IDE is multiwin, with a MDI inside.
Title: Re: How to create a window with panes
Post by: Greenhorn on February 06, 2022, 01:04:44 AM
Quote from: NoCforMe on February 05, 2022, 01:43:15 PM
So let's say a guy wants to create an application with a window containing several panes, something like OllyDbg, where the panes are linked together and mutually resize and all.

How would he do that? Is this something that requires Visual Studio? MFC? Can ResEd create something like this? Is it possible to "roll your own" (even though I'm sure that would be more work)? Perplexed here.

In WM_SIZE use MoveWindow or better DeferWindowPos to arrange the child windows.
https://riptutorial.com/winapi/example/8080/wm-size

QuoteOK, but how do you get those shared borders and dividers? Those don't just happen when you put windows next to each other.
There is no common control for that. In a plain Win32 application, typically the main window is responsible to do this. Or you create your own "divider control".
http://www.catch22.net/tuts/win32/splitter-windows
Title: Re: How to create a window with panes
Post by: hutch-- on February 06, 2022, 06:46:06 AM
In a single plane, think of 3 CreateWindowEx() windows side by side. The left one is a normal interface windows, the middle one is the splitter window and the right side one is another normal interface windows. The splitter window is where the control of resizing the left and right windows is performed. By using the mouse location, you can drag the splitter left or right. Within the control of the mouse moving the splitter window, you use MoveWindow() to control all 3 windows.

The left side window has its right side border changed. The splitter window maintains its width and the right side window is moved left to right with its right side border restricted to the right side of the parent window.
Title: Re: How to create a window with panes
Post by: wjr on February 06, 2022, 08:30:09 AM
My Skeleton - Alive and Kicking example http://wjradburn.com/software/Skeleton.zip (http://wjradburn.com/software/Skeleton.zip) has two child windows using the main window to process messages for the "splitter bar" which is just the space between the two panes. A similar approach could be used for more panes, but would be a bit extra work for horizontal and vertical splits as in OllyDbg.
Title: Re: How to create a window with panes
Post by: NoCforMe on February 06, 2022, 12:28:41 PM
Splitter bar--that's the key thing I was looking for. Looking at "Alive and Kicking" now. Thanks!
Title: Re: How to create a window with panes
Post by: HSE on February 06, 2022, 12:42:39 PM
Also there is an Splitter example in Masm32 SDK, inside exampl03 directory.
Title: Re: How to create a window with panes
Post by: NoCforMe on February 06, 2022, 01:24:39 PM
So the "splitter" is really just that little slice of the underlying parent window that shows through between the child windows, because the only time the parent window will get mouse messages is when the mouse is over that little sliver; all other messages will go to the children. Neat. And I was wondering how the application I was looking at got a special cursor to move the splitter, but that's just a matter of loading that cursor for the underlying window.
Title: Re: How to create a window with panes
Post by: jj2007 on February 06, 2022, 08:48:59 PM
Exactly. And while user passes the mouse from left to right, from one control to the neighbouring one, the main WndProc receives a bunch of messages:

msg     1285    WM_SETCURSOR
msg     1286    WM_SETCURSOR
msg     1287    WM_SETCURSOR
msg     1288    WM_SETCURSOR
msg     1289    WM_GETICON
msg     1290    WM_GETICON
msg     1291    WM_SETCURSOR
msg     1292    WM_NCHITTEST
msg     1293    WM_SETCURSOR
msg     1294    WM_MOUSEFIRST
msg     1295    WM_NCHITTEST
msg     1296    WM_SETCURSOR
msg     1297    WM_MOUSEFIRST
msg     1298    WM_NCHITTEST
msg     1299    WM_SETCURSOR
msg     1300    WM_MOUSEFIRST
msg     1301    WM_SETCURSOR
msg     1302    WM_SETCURSOR


WM_SETCURSOR looks promising ;-)
Title: Re: How to create a window with panes
Post by: TimoVJL on February 06, 2022, 09:08:46 PM
A splitter without own window / control have some flickery in slow PC, but not an problem anymore, but i was somewhere at 2003.
wjr examples might work in that principle, a parent window work as splitter.

EDIT:
//these are for splitter, begin
case WM_SIZE:
MoveWindow(hWndTV, 0, 0, uDrag-1, HIWORD(lParam), TRUE);
MoveWindow(hWndLV, uDrag+1, 0, LOWORD(lParam)-101, HIWORD(lParam), TRUE);
return 0;
case WM_LBUTTONDOWN:
SetCapture(hWnd);
bDrag = TRUE;
return 0;
case WM_LBUTTONUP:
ReleaseCapture();
bDrag = FALSE;
return 0;
case WM_MOUSEMOVE:
if (bDrag) {
GetClientRect(hWnd, &rect);
if ((LOWORD(lParam)>50) && (LOWORD(lParam)<(rect.right)-50)) {
MoveWindow(hWndTV, 0, 0, LOWORD(lParam)-1, rect.bottom, TRUE);
MoveWindow(hWndLV, LOWORD(lParam)+1, 0,
rect.right-LOWORD(lParam)+1, rect.bottom, TRUE);
uDrag = LOWORD(lParam);
}
}
return 0;
//these was for splitter, end

Interesting:
What's the point of DeferWindowPos? (https://devblogs.microsoft.com/oldnewthing/20050706-26/?p=35023)
Title: Re: How to create a window with panes
Post by: hutch-- on February 06, 2022, 09:15:10 PM
One of the toys in MASM32 is "qetb.exe" and that uses a 3 window design, the middle one being the splitter and as a separate window, you can change the splitter colour on mouse click. All done via MoveWindow().
Title: Re: How to create a window with panes
Post by: NoCforMe on February 07, 2022, 08:59:49 AM
Next question: let's say you have an app with 3 control windows, say one on the left and two stacked up vertically on the right. How to differentiate between landing on the vertical and horizontal splitters? (Because you want different cursors for them to guide the user.)

Maybe it's simple: if the cursor position is to the right of the vertical split, then load the vertical (north-south) cursor, else load the horizontal (east-west) one. Because if it's to the right of the vertical split, it must be somewhere over the horizontal split.
Title: Re: How to create a window with panes
Post by: daydreamer on February 07, 2022, 07:08:47 PM
You can probably solve it with code inside Wm_SetCursor message
https://docs.microsoft.com/en-us/windows/win32/learnwin32/setting-the-cursor-image
Title: Re: How to create a window with panes
Post by: TimoVJL on February 07, 2022, 07:24:48 PM
TLODBC_sHell had this kind of code with 3 panes:
dx and dy are just delta of mouse positions against drag X Y positions.
void OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
int dx, dy;
SetCapture(hWnd);

dx = x - uDragX;
if (dx > - 10 && dx < 10)
bDragX = TRUE;

dy = y - uDragY;
if (dy > - 10 && dy < 10)
bDragY = TRUE;
}

void OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
{
ReleaseCapture();
bDragX = FALSE;
bDragY = FALSE;
}

void OnMouseMove(HWND hWnd, int x, int y, UINT keyFlags)
{
RECT rc;
BOOL bMove;

int dx = x - uDragX;
int dy = y - uDragY;
if (dx > -5 && dx < 5)
SetCursor(LoadCursor(NULL, IDC_SIZEWE));
else if (dy > -5 && dy < 5)
SetCursor(LoadCursor(NULL, IDC_SIZENS));
else
SetCursor(LoadCursor(NULL, IDC_ARROW));

bMove = FALSE;
GetClientRect(hWnd, &rc);
if (bDragX && !bDragY) // X
{
if (x > 50 && x < (rc.right - 50))
{
uDragX = x;
bMove = TRUE;
}
}

if (bDragY && !bDragX) // Y
{
if ((y > 50) && y < (rc.bottom - 50))
{
uDragY = y;
bMove = TRUE;
}
}
if (bMove)
{
ReSizeWindows(hWnd);
}
}
Title: Re: How to create a window with panes
Post by: NoCforMe on February 07, 2022, 07:40:54 PM
Yes, I think that confirms what I speculated about above.
Back to the laboratory!
Title: Re: How to create a window with panes
Post by: jj2007 on February 08, 2022, 06:53:32 AM
My first attempt, but I'm not satisfied - it's slow and flickery.

Extract files to a folder and launch the exe.
Title: Re: How to create a window with panes
Post by: Biterider on February 08, 2022, 07:41:56 AM
Hi
Maybe you can get inspiration from one of the ObjAsm examples.  :cool:

Regards, Biterider
Title: Re: How to create a window with panes
Post by: jj2007 on February 08, 2022, 08:14:53 AM
Quote from: Biterider on February 08, 2022, 07:41:56 AM
Maybe you can get inspiration from one of the ObjAsm examples.  :cool:

Thanks, it works fine, and no flicker, but in contrast to mine you don't update the controls while you are dragging.

I'll have to study \Masm32\examples\exampl03\splitter\splitter.asm, it updates while dragging but more smoothly than mine :cool:
Title: Re: How to create a window with panes
Post by: NoCforMe on February 08, 2022, 04:35:40 PM
JJ, the problem I have with your example is not so much flicker as the annoyance that I have to drag the splitter really S-L-O-W-L-Y or else it escapes my grip. Reminds me of a program I wrote that moves things (control windows) around in a parent window and lets you resize them: really flaky behavior; sometimes things jump erratically, etc. Apparently this is more of an art than a science.
Title: Re: How to create a window with panes
Post by: hutch-- on February 08, 2022, 06:07:00 PM
The notation is PowerBASIC but you do the same thing in assembler.

        MoveWindow hSplitter,splitr-2,rbh,5,Rct.nBottom-(rbh+sbh),%TRUE
        MoveWindow hEdit,splitr+1,rbh,Rct.nRight-splitr-1,Rct.nBottom-(rbh+sbh),%TRUE
        MoveWindow hList,0,rbh,splitr-1,Rct.nBottom - (rbh + sbh), %TRUE

Flickering.
    wcex.hbrBackground = %NULL   ' set the background brush to 0 or NULL

Title: Re: How to create a window with panes
Post by: jj2007 on February 08, 2022, 08:26:24 PM
Quote from: NoCforMe on February 08, 2022, 04:35:40 PM
JJ, the problem I have with your example is not so much flicker as the annoyance that I have to drag the splitter really S-L-O-W-L-Y or else it escapes my grip.

I know. I've tried with WM_MOUSEMOVE instead of WM_SETCURSOR, no change. I need to rethink the logic a little bit (if I find the time).

Attached a C source from an obscure web location. It's 140 lines short, but my three C compilers bark at them, for various reasons. C/C++ is a waste of time.
Title: Re: How to create a window with panes
Post by: TimoVJL on February 09, 2022, 06:11:24 AM
No compiling problems with Pelles C 11

EDIT: without CRT too.
Title: Re: How to create a window with panes
Post by: NoCforMe on February 09, 2022, 01:23:01 PM
Quote from: jj2007 on February 08, 2022, 08:26:24 PM
Attached a C source from an obscure web location. It's 140 lines short, but my three C compilers bark at them, for various reasons. C/C++ is a waste of time.
Here, I translated it to MASM (vanilla) for you. Works, Whoop-te-do.
Title: Re: How to create a window with panes
Post by: jj2007 on February 09, 2022, 07:46:35 PM
Thanks, that's a nice action by somebody whose name is no C for me :tongue:
Title: Re: How to create a window with panes
Post by: hutch-- on February 09, 2022, 09:14:21 PM
 :rofl:
Title: Re: How to create a window with panes
Post by: jj2007 on February 09, 2022, 10:13:29 PM
Quote from: TimoVJL on February 09, 2022, 06:11:24 AM
No compiling problems with Pelles C 11

Thanks, Timo. I guess I must check my version :rolleyes: