Search code examples
c++algorithmwinapilinediagram

How do I link 2 static windows inside the main window with a line?


I have to code a "logical scheme/diagram builder" and I've decided to do it in WinApi because I thought it would be easier but now i have a problem.

This is what I want to do:

image

I've managed to do the blocks (START, STOP etc) and write in them, as static windows, and I've managed to do a simulation of the drag and drop process but I've been searching for 6 hours for information about how I can link the blocks with a line, the line should still be linked between the two blocks even after they were moved.

I can post some parts of the code if you need it, it has 650 lines so I've decided not to throw it all here.


Solution

  • This is a broad question, and without code, I can only give you general guidance. Anyway, it would be too time consuming to write the code here (I have already developed several such graphic tools).

    I understand that you can work and draw with WinAPI. So you can draw the two blocks that you want to link and therefore you always know the coordinates of the boundary-lines of each box.

    First level

    When you add a line linking two blocks you need to keep track of the source and target block. Everytime you draw the diagram:

    • you calculate dynamically the begin and end point of your line, based on the coordinates of the related boxes.
    • You can do by chosing the closest boundary of each box. In your example between START and READ X you'd take the bottom boundary of the START box (so the highest y in the box coordinates), and the top boundary of the READ X box (so the smallest y in the box coordinates).
    • Start simple: take always the middle point of the relevant boundary, so (smallest_x + largest_x)/2
    • Once you have the coordinates draw the line.

    You'll get for now a direct line. It's a good start. But if the boxes are not aligned, it will look ugly.

    Second level

    The next thing is to decompose your line into horizontal and vertical sublines. This is slightly more complex:

    • If the middle x of the target box is beyond the right border, or before the left border of the source box, you will choose to exit the source through the right or the left border (the middle). Else you will exit through the bottom or the top border of the box (depending on what's closest).
    • If the middle y of the target is between the upper and lower y of the source, you will enter the tartget via the closest of the left or the right line of the target box. Else the closest of the upper or lower one.
    • If you got a combination of vertical horizontal border, just draw the lines starting from the middle of each border (one vertical, one horizontal).
    • If you have a combination of two boders of the same direction, if their middle is aligned you'll have a straing line. Otherwhise, you'll need to draw three lines.

    Third Level

    The level 2 will work and set automatic lines for simple diagrams like the one you have as example. If it might get more complicated, you need to modify your line model and let the user decide on the path.

    This means that eventually the user may chose the side of the box source and target box, and the location on that side. You then need to store this information in your line object. The location on the line should be kept proportionally, so that this information is not outdated when you scale the diagram.

    The user may also want to chose where to break the line into horizontal and vertial component, and even route the line around and object. THis means that you may also have to keep track of these intermediary points in your line object.

    I would however advise you not to start with level 3, since this is much more complex, not only in the drawing, but also in designing the user interface that will allow the user to add/remove these line settings.