I'm making a game of connect 4 in delpi. I need to put the correct coloured circle in the correct place, according to where the user has clicked. How do you load an image (JPEG prefereably) into a specific cell?
I have no idea where to start with this (because my teachers are useless lol) so any help would be so appreciated.!!
on form create:
images:=timagelist.Create(self);
image1:=tjpegimage.Create;
image2:=tjpegimage.Create;
bimage1:=tbitmap.Create;
bimage2:=tbitmap.Create;
try
image1.loadfromfile('red.jpg') ;
bimage1.Assign(image1);
image2.loadfromfile('yellow.jpg') ;
bimage2.Assign(image2);
finally
image1.free;
image2.free;
end;
images.Add(bimage1,nil);
images.Add(bimage2,nil) ;
on drawcell:
row:=c4grid.Row;
col:=c4grid.Col;
images.Draw(c4grid.Canvas,row,col,0);
So far nothing happens, and there is no evidence that you can actually click the cell. Any help/advice/guidance would be much appreciated!
Related
cxDbImage loads a picture from database. Kind of thumbnail.
How can I have this pictures shown a little bigger out of the cxdbimage
container when I click on the picture inside ?
I have some projects that use this kind of functionality. I simply have created a form with a TcxImage inside (align alClient).
Then, on cxDbImage DbClick event, I just perform something like this:
FMyForm := TMyForm.Create(Self);
try
FMyForm.cxImage1.Picture := cxDBImage1.Picture;
FMyForm.ShowModal;
finally
FreeAndNil(FMyForm);
end;
If I understood your question correctly, this approach can help you.
I seem to have a mental block with this one.
I need to save recent changes to a Record. I am doing it OK with buttons for "New" "Edit" "Post" "Next" etc but when a user double-clicks a DBGrid, it is now too late to make changes as the DBGrid selection has moved the database cursor to the selected record.
I can't use AutoUpdate as the data that may have been changed is not something the user would have directly entered, it is a value that is changing all the time.
I'll try to describe it better: While the user is reading a Test-page, a timer is counting down or up. When they click the "Next" or "Prior" buttons I can save the timer setting. But, if they Double-Click the DBGrid I have no way of first changing the current Record before the selection moves to the clicked-Record.
I tried using the
Procedure TForm1.tblTestOnBeforeScroll(...
begin
tblTest.Edit;
tblTest.FieldByName('TimerCt').AsInteger:=ClockCtr;
tblTest.Post;
end;
But, that crashed the database, not surprisingly, but I thought I would give it a try before asking here.
How do I deal with the current record? I do not want to disallow the double-click if possible as it seems nice and intuitive for the user.
I'm afraid that what you do on DBGrid is a wrong in concept action.
Key point is DBGrid is a data aware control. So everything you do on it must based on it's datasource then it's dataset.
There is a DblClick event on TDBgrid. But still you have to check it's dataset to see what record is active.
The code you shown above clearly lead you to an endless loop.
When you doing a scroll, the dbgrid will call OnBeforeScroll event, moving the active record
and call OnAfterScroll. Your OnBeforeScroll code does an data update. Then dbgrid abort its operation cause of data change. Then after data update, it try to scroll again, and the data change happen again. Endless loop happen here.
best regard
Apologies in advance if I'm misunderstanding you, but it seems to me that either the premise of your question is wrong or there is something relevant you haven't told us about what you're doing. Please try the following:
If you don't have one already, please temporarily add a DBNavigator to your form and connect it to the same DataSource as your DBGrid. The point of doing this is so that you can more clearly see what's going on.
Then, in your DBGrid's Options, set dgEditing to True.
Finally, comment out or disable your BeforeScroll handler, save and run your program.
Now, click once in some cell in your DBGrid that contains a value which it's ok to change. Click it a second time so that it selects the value in the cell rather than the cell per se.
Make some change to the cell value, but do nothing else for the time being. You should notice that a) the current record indicator of the DBGrid has changed from a black triangle to an I-Beam graphic, like ][ and b) that the tick and cross buttons of the DBNavigator are now enabled.
Now, without doing anything else on the form, click in another row of the DBGrid. You should find that a) the change to what was the current record in step 5 has been saved and b) the current row indicator reverts to the black triangle and the DBNav's tick and cross buttons are disabled.
(If you don't get the behaviour I've just described, create a minimal new project and try that instead, as some other change you've made in your existing project may be interfering with it).
What I've described in 5 & 6 is the default behaviour of a DBGrid and insofar as I understand your q, that seems to be the behaviour you're trying to achieve. If that's not the behaviour you want, please explain exactly how what you do want differs. It's not clear to me where the user double-clicking on the grid comes into your q, except that that action may move the dataset's cursor (if the dbl-click is on a different row than the current one), but as the default DBGrid behaviour will save changes to the current row before it moves the dataset's cursor, it will do what you seem to want automatically.
Btw, what "AutoUpdate" do you mean? Did you mean TDataSource's AutoEdit property?
Before I start I want to explain that I'm looking for a general solution to my inquiry, I don't have any code to show because I haven't the faintest idea of how to start. Let's say I have a program in which I have 4 buttons, two on the right (red and blue), two on the left (white and yellow). If I were to press a certain combination of buttons I want to get a specific output an example would be if I touch the red button and then the white one the word "cow" appears or if were to touch the white one then the red one the word "chicken" appears. Is there any documentation that anyone knows of that can help me with my problem? Can this even be done with an array?
HotLicks has a valid answer, but I think an NSDictionary is a better solution. Create keys based on button presses, like:
#{ #"RedWhite" : #"Cow",
#"WhiteRed" : #"Chicken" };
Your code will be easier to read, and you can support three presses easily (assuming you're working with a timer that you invalidate after each press) by just adding another key; no recalculating your array:
#{ #"RedWhiteBlue" : #"America" };
I'm using a TVirtualStringTree as a grid which is working pretty well.
I'm using the treeviews hint functionality to show a hint when the user positions the mouse over a cell. I've had to change HintMode to hmHint as I want my hints to appear regardless of the cell text length.
What I'm trying to do now is to display a different hint depending on whereabouts the mouse is within the cell.
I can do this no problem before the hint is displayed by using the OnGetHint event. My problem is this event is only raised a next time when the user moves the mouse to another cell.
I can't see to find a way to update the hint while its displayed and the mouse is moved within the same cell
I've looked at suggestions for other controls, using the Application's OnShowHint event but they just seem to make the hint disappear and not show again.
Anyone got any ideas?
Thanks
Update
After some investigation here is what I have found in case it helps someone come up with a solution:
The CMHintShow method sets the CursoRect field of the HintInfo record to the bounds of the cell. This seems to stop the VCl from triggering the hint code again until the mouse moves out of this rect (TApplication.HintMouseMessage).
If i set the CursorRect to something smaller than the cell bounds the hint will update. I use VTs in a few places for different purposes, so I can't make these changes directly. Would be good to get a solution that doesn't require this change.
In TBaseVirtualTree.CMHintShow right near the top, the code reads:
if PtInRect(FLastHintRect, HintInfo.CursorPos) then
Exit;
If you comment this out then the behaviour is closer to what you are looking for. The hint window won't show again if you move the mouse within the same cell, but if you click then it will.
I can't seem to find any way to make the hint window show in the same cell without that mouse click though!
Sure I've seen this done before but off-hand I can't find any examples.
I've got a TListView, set in 'report' viewstyle. It has about half a dozen subitems, and one thing we'd like to do is have the 'hint' (tooltip) on the listview dynamically show another field of data. That is, each time you move the mouse over any given row, the 'hint' would show some text relevant to that particular row.
I'm partway there - I can do this using the OnInfoTip method, but unfortunately once a tip has appeared, Windows seems to decide that I don't need to see a hint for the listview again until I move the mouse away from the listview and then back 'over' it again. Simply moving the mouse down to the next row, all-the-time keeping the mouse over the control, doesn't persuade the program to display the new hint.
Just to be clear - I've got OnInfoTip working so that the program does display the right hint relevant to the item I first moved the mouse over. Changing the hint text isn't the issue. The problem is that moving the mouse to another item in the listview doesn't cause the software to show a new hint. (Hope that makes sense).
Is there some proper way of getting this behaviour to work, or am I going to end up doing something icky with mouseovers and then manually drawing a hintbox (etc)?
check the following link:
Display Custom Hints for TListView Sub Items
Edit:
I just checked it now on delphi7 it's showing the hint for every row dynamically after moving the mouse on the listview.
Offtopic: This is simple in Virtual Treeview component, it is build-in feature.
i was using the OnInfoTip event (i didn't need hints for the subitems). the hint was "flashing" (show/hide/show/hide/show/hide/show/hide). found the listview's ShowHint was false. set it to True and it worked as it should.