News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

How to create a window with panes

Started by NoCforMe, February 05, 2022, 01:43:15 PM

Previous topic - Next topic

HSE

Also there is an Splitter example in Masm32 SDK, inside exampl03 directory.
Equations in Assembly: SmplMath

NoCforMe

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.
Assembly language programming should be fun. That's why I do it.

jj2007

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 ;-)

TimoVJL

#18
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?
May the source be with you

hutch--

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().

NoCforMe

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.
Assembly language programming should be fun. That's why I do it.

daydreamer

You can probably solve it with code inside Wm_SetCursor message
https://docs.microsoft.com/en-us/windows/win32/learnwin32/setting-the-cursor-image
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

TimoVJL

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);
}
}
May the source be with you

NoCforMe

Yes, I think that confirms what I speculated about above.
Back to the laboratory!
Assembly language programming should be fun. That's why I do it.

jj2007

My first attempt, but I'm not satisfied - it's slow and flickery.

Extract files to a folder and launch the exe.

Biterider

Hi
Maybe you can get inspiration from one of the ObjAsm examples.  :cool:

Regards, Biterider

jj2007

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:

NoCforMe

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.
Assembly language programming should be fun. That's why I do it.

hutch--

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


jj2007

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.