Solved

Another Cards.dll question

Posted on 1998-04-15
7
176 Views
Last Modified: 2008-02-01
ret = cdtDraw(frmcard.hDC, cardleft, cardtop, shuffle(X), C_FACES, &HFFFF&)
 This paints a card in my form, fine now I want to pick it up and move it. Where the heck is it? I have
examined the code of qcards32.dll a sample, there is not pics or image boxes just the form
Something like frmcard.hdc.mycard(x) would be nice. I know where the card is on the form (x,y) but
am stumped, even BitBlt needs some object to work with. I guess the big question is can I make the
result of the draw call an object, it yes, how....
0
Comment
Question by:kbrock
  • 4
  • 3
7 Comments
 
LVL 6

Expert Comment

by:clifABB
Comment Utility
You should be painting the cards on Pictureboxes (or better image controls)
0
 

Author Comment

by:kbrock
Comment Utility
Thanks clifABB, I have had it working with the picture boxes, OK, However, when I was playing with this qcards.dll I found on the net, the demo form which dragged cards and various other stunts used no picture boxes or image controls. My question is, how the heck are they being moved. Im more curious than anything, I feel there is something Im missing. Unfortunatly the buy who wrote qcards32.dll is missing and cant be queried on this problem. Please try again. Is It possible to create a custom control to deal with the cards. Im not sure what goes on inside the custom dll. Does ms use picture boxes in their solitair game?

0
 
LVL 6

Expert Comment

by:clifABB
Comment Utility
I have a copy of the old qcards.dll from many years ago.  Let me take a look over the weekend and I'll see what I can do.
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 6

Accepted Solution

by:
clifABB earned 100 total points
Comment Utility
I copied this out of the example for qcards32.dll:

Place the following in the declarations section of your form (unless they already exist):
Dim Counter(1 To 4) As Integer
Dim CardArray(1 To 4, 1 To 26) As Integer
Dim Temp() As Long
Dim DblClickX As Integer
Dim DblClickY As Integer
Dim nSourceCard As Integer
Dim OldX As Integer
Dim OldY As Integer
Dim bSingleDragging As Integer
Dim bBlockDragging As Integer
Dim nSourceArrayID As Integer
Dim nSourceArrayPos As Integer
Dim nItems As Integer
Dim bMouseMoved As Integer
Dim nDestCard As Integer
Dim nDestArrayID As Integer

Place the following code in your forms MouseDown event:

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)

  Dim nStatus As Integer
  nSourceCard = InitDrag(Form1.hwnd, x, y)
  If nSourceCard = 0 Then
    ' no card selected
    AbortDrag
  Else
    ' save old position for later use
    ' if the drag is invalid
    OldX = GetCardX(nSourceCard)
    OldY = GetCardY(nSourceCard)
    ' if card is not blocked, it is a single drag
    ' if it's blocked, it means were doing a block drag
    nStatus = GetCardBlocked(nSourceCard)
    If nStatus = 0 Then
      bSingleDragging = True
    Else
      bBlockDragging = True
    End If
  End If
End Sub

Place the following code in your form's MouseMove event:
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)

  If bSingleDragging = True Then
    ' if just a single card, it's number was set with InitDrag call
    DoDrag Form1.hwnd, x, y
  ElseIf bBlockDragging = True Then
    ' determine which pile we are dealing with
    nSourceArrayID = GetUser4(nSourceCard)
    ' determine the position of the first card in drag
    nSourceArrayPos = GetUser3(nSourceCard)
    ' how many cards are we moving
    nItems = Counter(nSourceArrayID) - nSourceArrayPos + 1
    ' create an array to hold the numbers of the cards to move
    ' and fill the array starting at 0
    ReDim Temp(nItems)
    For i = nSourceArrayPos To Counter(nSourceArrayID)
      Temp(i - nSourceArrayPos) = CardArray(nSourceArrayID, i)
    Next i
    ' pass the BlockDrag sub the actual array, referencing it's
    ' first element. This acts as a "pointer" to the rest of
    ' the elements in the array in memory
    BlockDrag Form1.hwnd, Temp(0), nItems, x, y
    ' let the MouseUp event know that it is ok to
    ' reference the Temp(0) array for this instance
    bMouseMoved = True
  End If
End Sub

Place the following code in your form's MouseUp event:

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)

' most of the code here involves relocating cards
' to their new homes/arrays

  Dim nDeltaX As Integer
  Dim nDeltaY As Integer
  Dim nSourceX As Integer
  Dim nSourceY As Integer
  Dim nNewX As Integer
  Dim nNewY As Integer
  Dim nUnused As Integer
  Dim nSourceColor As Integer
  Dim nDestColor As Integer

  If bSingleDragging = True Then
    ' end the drag operation and
    ' find out who we are dropping in on
    nDestCard = EndDrag(Form1.hwnd, x, y)
    nSourceColor = GetCardColor(nSourceCard)
    nDestColor = GetCardColor(nDestCard)
    nSourceArrayPos = GetUser3(nSourceCard)
   
    ' do some color testing
    ' only allow drop if source and destination colors are the same
    ' and if nSourceCard is not the last card in it's pile.
    ' if nDestCard is 0, the Source Card was dropped at an invalid location
    If nDestCard = 0 Or nSourceColor <> nDestColor Or nSourceArrayPos = 1 Then
      ' if not a valid drop site, return drag
      ReturnDrag Form1.hwnd, nSourceCard, OldX, OldY
      bSingleDragging = False
    Else
      ' valid single drag/drop... proceed with relocation
       
      ' which array did we come from
      nSourceArrayID = GetUser4(nSourceCard)
      ' reduce our old array counter
      Counter(nSourceArrayID) = Counter(nSourceArrayID) - 1
      ' which array are we joining
      nDestArrayID = GetUser4(nDestCard)
      ' add another to it's counter
      Counter(nDestArrayID) = Counter(nDestArrayID) + 1
      ' block our new neighbor
      AdjustCardBlocked nDestCard, True
      ' install our new arrayID and position
      SetUser3 nSourceCard, Counter(nDestArrayID)
      SetUser4 nSourceCard, nDestArrayID
      ' align with left side of card above us
      ' and down OFFSET (16)
      nNewX = GetCardX(nDestCard)
      nNewY = GetCardY(nDestCard)
      RemoveCard Form1.hwnd, nSourceCard
      DealCard Form1.hwnd, nSourceCard, nNewX, nNewY + OFFSET
      ' unblock last card in old array
      AdjustCardBlocked CardArray(nSourceArrayID, Counter(nSourceArrayID)), False
      ' add ourselves to new array
      CardArray(nDestArrayID, Counter(nDestArrayID)) = nSourceCard
      bSingleDragging = False
    End If
ElseIf bBlockDragging = True And bMouseMoved = True Then
    ' we can reuse the Temp() array from MouseMove
    ' as long as MouseMove actually occurred
   
    ' end the drag and find out the destination card
    nDestCard = EndBlockDrag(Form1.hwnd, Temp(0), nItems, x, y)
    nSourceColor = GetCardColor(nSourceCard)
    nDestColor = GetCardColor(nDestCard)
    nSourceArrayPos = GetUser3(nSourceCard)
    ' do some color testing
    ' only allow drop if source and destination colors are the same
    ' and nSourceCard is not the last card in it's pile
    If nDestCard = 0 Or nSourceColor <> nDestColor Or nSourceArrayPos = 1 Then
      ' if not a valid drop site, return drag
      ReturnBlockDrag Form1.hwnd, Temp(0), nItems, OldX, OldY

      bBlockDragging = False
      bMouseMoved = False
    Else
      ' which array did we come from
      nSourceArrayID = GetUser4(nSourceCard)
      ' reduce our old array counter
      Counter(nSourceArrayID) = Counter(nSourceArrayID) - nItems
      ' which array are we joining
      nDestArrayID = GetUser4(nDestCard)
      ' block our new neighbor
      AdjustCardBlocked nDestCard, True
     
      ' this bit of code demonstrates how you can "fool" a drag operation
      ' to drag the item to a specific location. Usually, you pass the
      ' BlockDrag sub the x,y location of the mouse. If you first determine
      ' your current mouse position in relation to the object you are dragging
      ' you can add that difference (nDeltaX, nDeltaY) to the position you
      ' want to drag to, and pass those points to BlockDrag. We want to align
      ' with the left side of DestCard and down OFFSET (16) pixels from its top
      nNewX = GetCardX(nDestCard)
      nNewY = GetCardY(nDestCard)
      nSourceX = GetCardX(nSourceCard)
      nSourceY = GetCardY(nSourceCard)
      nDeltaX = x - nSourceX
      nDeltaY = y - nSourceY
      nUnused = InitDrag(Form1.hwnd, x, y)
      BlockDrag Form1.hwnd, Temp(0), nItems, nNewX + nDeltaX, nNewY + OFFSET + nDeltaY
      nUnused = EndBlockDrag(Form1.hwnd, Temp(0), nItems, nNewX + nDeltaX, nNewY + OFFSET + nDeltaY)
       
      ' install our new arrayIDs and positions
      For i = 0 To nItems - 1
        Counter(nDestArrayID) = Counter(nDestArrayID) + 1
        CardArray(nDestArrayID, Counter(nDestArrayID)) = Temp(i)
        SetUser3 Temp(i), Counter(nDestArrayID)
        SetUser4 Temp(i), nDestArrayID
      Next i
       
      ' unblock last card in old array
      AdjustCardBlocked CardArray(nSourceArrayID, Counter(nSourceArrayID)), False
       
      ' remove temporary block on last card in block drag array
      AdjustCardBlocked Temp(nItems - 1), False
       
      bBlockDragging = False
      bMouseMoved = False
    End If

  ElseIf bBlockDragging = True And bMouseMoved = False Then
    ' There was a MouseDown event but no MouseMove event
    AbortDrag
    bBlockDragging = False
  End If
End Sub
0
 

Author Comment

by:kbrock
Comment Utility
Thankyou ClifABB, I have been playing with qcard as I mentioned earlier on. You had said before that I was to use image boxes to hold the cards. I seems to me he is using a bitblt function to move the cards directly.
ie draw(me.hdc,xpos,ypos, blah blah) draws the card on the form no pic or image box.
I can live with that. As you might notice qcards is a custom DLL. Back to cards.dll now and my origonal question. Do you think ms is using bitblt to drag and move the cards?
If so now here is the 50 dollar question. How does a drag work using bitblt?
Thanks for your patience. Im going average for the last answer as it really skirted the main issue. By the way my email is kbrock@direct.ca if you are in the mood to do some one on one.


0
 
LVL 6

Expert Comment

by:clifABB
Comment Utility
I'm sure bitblt is the way MS does it for both drawing and dragging as well.

Ok, here's how I would do it, if I had a mind...

1. BitBlt an image of the form (window) (without the cards) and copy it into memory using CreateDC.

2. BitBlt the image of the card you are going to move and copy it into memory.

3. BitBlt (from the memory DC) the area where the card was and put it in the place where you moved the card from.

4. BitBlt the card from memory to the new position.

You must keep track of the position of each card (all 52).

This may seem like it's memory intensive, but the average user's computer can handle it.  For all the other's, well, that's why there's an option to drag just the card's outline.

This is basically what is done in the solitaire game that comes with Windows.
0
 

Author Comment

by:kbrock
Comment Utility
Thanks clifABB, I was closing in on createDC, Will post at next jamup.

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now