Jump to content

dadreamer

Members
  • Posts

    349
  • Joined

  • Last visited

  • Days Won

    33

Everything posted by dadreamer

  1. First, C unions are special data type that allows for multiple data types to be stored in the same location. Therefore you don't need to bundle each and every field defined in your header for that union. The union length is set by the longest field. So you should pass 4 bytes in both of your cases. It's up to the code on how to interpret that union onwards: either as uint32_t "value" or as four uint8_t fields struct. Second, you have two pointers in your main struct (pImagePtr and pUserPtr). You should pass them as 32-bit fields in 32-bit LabVIEW or 64-bit fields in 64-bit LabVIEW. To satisfy both cases, use Conditional Disable Structure with two cases for 32- and 64-bits accordingly. Now you're passing U8 fields, that will likely lead to writing to the neighboring fields inside the shared library. The same applies to size_t parameters (read here for details). Maybe it would even be easier to make two different structs for 32- and 64-bits in Conditional Disable Structure instead of defining each parameter separately.
  2. No, don't pass LabVIEW arrays straight to the cluster! They are different entity than those in C/C++. In order to match your struct definition, you have to turn each array into a separate cluster. Use Array To Cluster primitive for that. RMB click -> Cluster size on it allows you to specify the output cluster size. Then bundle all the clusters into one (plus three int parameters), then pass that resulting cluster to your CLFN. I assume, you know your .so's calling convention. Oh, I forgot to add, that Array To Cluster node doesn't accept more than 256 elements. So, if SV_STRING_SIZE is 512, you need to make a pairs of 256+256 elements (e.g., two "id" clusters, two "vendor" clusters etc.). There's another way with DSNewPtr+MoveBlock, but it's a bit more advanced.
  3. So instead of the "IMG tab" wire, shown on your diagram, you now have a memory pointer to the data (of the same representation and layout)? If so, just MoveBlock it to a common LabVIEW array and proceed as usual. Also I slightly don't get the reason why you're doing two Marshal.Copy operations... On the diagram above that empty bitmap's data is copied into the LabVIEW array, then it is replaced with the "IMG tab" data (Replace Array Subset on zero row) and then the array is copied into the empty bitmap. Isn't it enough to copy the "IMG tab" data to the empty bitmap and do the rest of the code (UnlockBits etc.)? I can't run the snippet, as LAVA seem to strip the metadata out of the snippets.
  4. I'm afraid, no way around that. I mean, without A LOT of low-level hackery. IMAQ images have borders 3 pixels wide by default, whereas LabVIEW arrays don't have those. And not every VI from the Array palette works in-place, not producing a copy. Of course, you may read/write pixels data by its pointer using MoveBlock. Like this: But I wouldn't expect more than that. You can always move the image processing into your DLL/SO and write everything in pure C/C++, C# et cetera.
  5. If you are using VDM, you should already have the basic example on how to manipulate the IMAQ image in a shared library: IMAQ GetImagePixelPtr Example Don't know, if you will gain anything in terms of performance, but worth a try at least.
  6. Maybe this will help: Programmatically Scroll Front Panel Using LabVIEW
  7. I think Andrey won't mind if I repost this here.
  8. You can download PID and Fuzzy Logic Toolkit 2012, then unpack it somewhere (e.g., on your Desktop). Run this command in the admin command line: msiexec.exe /a "C:\Users\User\Desktop\2012PIDFuzzy\Products\LabVIEW_PID_Toolkit_2012\NIPID00\NIPIDToolkit.msi" /qb TARGETDIR="C:\Users\User\Desktop\2012PIDFuzzy\Products\LabVIEW_PID_Toolkit_2012\NIPID00\NIPIDToolkit" (Replace "User" with your username). Now go to \2012PIDFuzzy\Products\LabVIEW_PID_Toolkit_2012\NIPID00\NIPIDToolkit\ProgramFilesFolder\National Instruments\LabVIEW 2012\vi.lib\addons\control\pid\pid.llb and there you should have PID.vi along with many other VIs from that toolkit. Also note that some VIs use 32-bit lvpidtkt.dll, so it won't go in 64-bit LabVIEW.
  9. They introduced a token for smooth lines: SmoothLineDrawing=False
  10. The Type Spec Structure is accessible in LabVIEW 2017, if SuperSecretPrivateSpecialStuff=True is written to labview.ini and the user RMB clicks on the Diagram Disable Structure and chooses "Replace With Type Specialization Structure" menu entry.
  11. Darn, I'm slow Started to upload my disks to GDrive and on finish saw your message. Anyway, good to know it's resolved.
  12. Yes, looks much like you meant the 2D Picture pixmaps opcodes. Their names are similar to those from the QuickDraw PICT Opcodes document (e.g., frameArc, paintArc), but the values are different. On classic Mac OS I've seen the following. If a vector PICT image (of kLVPictImage type) is placed onto the panel and resized, it is redrawn as if it was a LV native kPiccImage. But when the VI is moved onto another platform, such as Windows, the image becomes a common bitmap, losing all its vector abilities. Seems, the presence of a platform-dependent API (such as QuickDraw) really matters. I'd add dynamic (un)registration of the drawing procedures for the cosmetics. It would allow to add custom decorations relatively easy, even though the Drawing Manager is undocumented to use in the DLLs. Currently no way to add the user decor, not having LV sources. But honestly all this legacy tech should be rewritten or even removed/replaced by something much better. EMF/WMF support is not that good and SVG is still not considered. 😿 By the way. This thread seems incomplete after @flarn2006posted in his profile some info to obtain all the decorations from lvobject.rsc. Here's the VI to do that: All Cosmetics.viChoose the .mnu path on the FP, run this VI, then import the subpalette in the standard way (Tools -> Advanced -> Edit Palette Set). Most of "hidden" elements are not that interesting as they're of no use as stand-alone decorations. Some could be useful tho, like those DSC module graphics (valves, pipes etc.), except for the Multi-Segment Pipe, maybe, because it's not functional as a decor. Or how about some cool gradient decors?
  13. Have seen this statement of yours many times, but still don't see how you came to this conclusion. I investigated those built-in PICCs a bit. The "Cosm" resource forks in lvobject.rsc (labview.rsc in the old versions) don't contain any graphic operators. For example, this is how the Flat Box resource looks: 0000 0003 //cosmetic flags 0000 0000 00F0 0000 FFF0 FFF0 //rect 0010 0010 0000 0000 0200 0000 //symbolic color 0000 0000 0000 000B //image index to get later (e.g., 3D5) Now, this 0xB is just an index to the LabVIEW's internal structure, that can easily be observed in Heap Peek. Not very informative though. Here's the handler procedure address and some data, passed to it. Obviously not enough to do the drawing. This kPiccImage has 0x3D5 number assigned as well, which just indexes into the LabVIEW's internal table, looking like this: I marked the Flat Box line. Only two fields are here: the handler proc offset and the data, being passed into it. The data is in fact nothing more than the graphic attributes for the handler to draw, like the border width and the line style. Let's check this. I set the border width to 5 (instead of 1) and the line style to 0x11 (instead of 0x44). Easy to see: - Those PICCs are used in many places of the LV GUI. - Almost all the drawing work is done by the handler proc. - The procs and the attributes for the decorations/cosmetics are hard-coded inside LabVIEW. The proc itself uses the Drawing Manager functions to do the work. So, if it's the Flat Circle proc (to simplify), it behaves this way: DEmptyRect -> DSelectNormPen -> DPaintOval -> DSelectNormPen -> DFrameOval. It could easily be reproduced on the diagram: Draw Oval.vi The left circle is drawn from the diagram, the right one is a built-in decoration. Of course, it needs more work, when applied to a real project, as redrawing is necessary, when the window is resized, minimized, overlapped etc. The handler proc takes this job for the native cosmetics. So, I did not find anything that would resemble the Mac OS PICT format (version 2 or 1, at least). It is more like a "Picture in C" instead, as someone noticed earlier.
  14. I have LabVIEW 8.0 Professional distro on three disks, that I believe was downloaded from torrents a while ago. The overall size is 1,68 GB. I'm a bit unsure whether it's ok to post it here. If the admin/mod's let me, I'll post it (without a "cure", ofc). As an alternative you may stalk for it in Google or other search engines. With pot luck you'll find it.
  15. It's still on some trackers out there. Downloaded fine. This is the image without any hack tools inside. Or search the web for "NI.LabVIEW.v8.0.Real.Time.Module.ISO".
  16. Yeah, I was thinking of double numbers whereas dealing with 4-byte integers, hence the confusion. In that thread I was introducing a filler field of 4 bytes in 64-bit LabVIEW using Conditional Disable structure. That's unnecessary here.
  17. Seems like a feature really 🙂 I prefer not to use PN's without a serious need, as they run in UI thread, so have not tested that. It looks much like in this case the value is copied out of the DDO instead of the intermediate buffer. One way or another... it's working.
  18. Its value remains constant (until you press the color of your liking), but its cosmetic color does update, that's why the Get Image method works, for instance, so it's possible to "catch" the moment, when the color changes, if the appropriate logic is implemented in the VI. Basic example. ColorBox Tracking.vi
  19. No, not on the widget, you use Refnum to Pointer on the ColorBox control reference. After that you attach a debugger and study the memory dump to find out the cosmetics pointers in the data space (if you decide to go this route). You can get its HWND, but it's of no real use here.
  20. This is possible, but totally unreliable. The Color Picker code changes the colors of the cosmetic, that is a part of the FP object (the Blinking property does that too). VI Scripting doesn't provide a way to obtain the ref's to the cosmetic. Ok, we could use that Refnum to Pointer trick to get the object's data space pointer, but we can't go further without using constant offsets. First, we need to find the cosmetic address, second, we need to find the colors addresses. Having those we could read out the colors. It would work only if the object data space structure does not change. But it is known to change with a 100% guarantee between different LabVIEW versions (incl. patches and service packs), RTE's, bitnesses, platforms, sun and moon phases or whatever. Besides, you would have to adapt that hacky technique between the objects with different types (such as Color Box and Boolean), because their data spaces are different and the offsets wouldn't work anymore. Due to that I personally dislike to base software on internal tricks. It's often unstable and very difficult to support. There exists an easier and documented way to get the color while the Picker is on. Just grab the object picture with the Get Image method and compare it against some initial picture to determine whether the changes are in effect.
  21. Even though this Color Picker window is created by the OS API, it does not expose any properties or methods to the programmer. All the window handling is done in the LV core entirely. I won't suggest using ChooseColor or its .NET wrapper as I'm pretty unsure how to accomplish the task of mouse tracking there (maybe LPCCHOOKPROC callback function could be of some use, but it would require writing a DLL anyway). It would be much easier to create your own color picker SubVI with some means of interaction with the main VI. You can find some color chooser examples on NI forums, e.g. this one.
  22. I believe it is, at least for desktop platforms. Given the pointer that ArrayMemInfo outputs, I can subtract 4 bytes (for 1D array of U32) or 8 bytes (for 2D array of U32) from it and do DSRecoverHandle, that gives a valid handle. I can even get its size with DSGetHandleSize and it will correspond to the array size that was passed to the ArrayMemInfo (plus N I32-sized fields, where N is the number of the array dimensions). According to the doc's such as Using External Code in LabVIEW handles are relocatable and contiguous. Of course, Rolf could add more here. @Neil Pate If you wonder what that wrapper trick is, check this post. Using those tokens you could somewhat enhance your CLF Nodes and reduce time spent on each call.
  23. @Neil Pate As I can see, your pointer maths are okay, as long as you provide valid coordinates in Point 1 and Point 2 parameters. Thanks to @ShaunR it appears, that ArrayMemInfo has a bug, that's reproduced in 64-bit LabVIEW. I couldn't reproduce it in 32-bit LabVIEW though. The stride should not be zero, unless the array is empty, no matter if subarray or not. But even when the stride is 0, it shouldn't lead to crash, because in this case we're just writing into row 0 instead of intended one. To eliminate the bug influence (if any), you might not use the stride of ArrayMemInfo node, but use (Array Width x 4) instead as it's a constant in your case.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.