Calling NvAPI_GPU_SetEDID on Nvidia card - c#

How do you call this method on Nvidia GPU:
NVAPI_INTERFACE NvAPI_GPU_SetEDID (
NvPhysicalGpuHandle hPhysicalGpu,
NvU32 displayOutputId,
NV_EDID * pEDID
)
Src: http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/group__gpu.html#ga6a41b31dd9743120213435d985f8fbcf
I need to execute the above command to remove all EDID set on all DisplayOutputs on our new Quadro Graphics Cards. Based on the API documentation, I tried searching for NvPhysicalGpuHandle and came across this project/library:
https://github.com/openhardwaremonitor/openhardwaremonitor/blob/master/Hardware/Nvidia/NVAPI.cs
This does not have the method I need NvAPI_GPU_SetEDID
I am not hardware programmer, I just need to be able to call this one command. any ideas? Can this be achieved using nvapi.dll/nvapi64.dll via pinvoke or something?

I personally didn't test this, but you can try the library and see if it can set EDID information without any problem, if it fails, please open an issue.
https://github.com/falahati/NvAPIWrapper
Here is how you should do it,
First, you need to find the right DisplayDevice or GPUOutput that you want to write EDID information to. There are multiple ways to do so.
Get a list of all PhysicalGPUs in the system using the NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs() static method, then select the PhysicalGPU you desire based on your logic. After finding the right PhysicalGPU, use the NvAPIWrapper.GPU.PhysicalGPU.GetDisplayDevices() method to get a list of all connected DisplayDevices to that GPU and store the right one in a variable.
Instead of searching for connected DisplayDevices, you can also go for the GPUOutputs. Just like before, you first need to find the right PhysicalGPU and then you can get a list of all GPUOutputs using the NvAPIWrapper.GPU.PhysicalGPU.ActiveOutputs property and store the right GPUOutput in a variable.
Another way to find the right DisplayDevice is to go for a list of all Displays. To do so, you need to use the NvAPIWrapper.Display.Display.GetDisplays() static method. This returns an array of Displays. Then using the NvAPIWrapper.Display.Display.DisplayDevice property, you can get the corresponding DisplayDevice of a Display.
After finding the right DisplayDevice or GPUOutput, you should use the NvAPIWrapper.GPU.PhysicalGPU.WriteEDIDData() method. This method allows you to write EDID data stored in a byte array to the DisplayDevice or the GPUOutput you selected before.
Note: Make sure to capture NVIDIAApiException and check for the NVIDIAApiException.Status property in case something went wrong.

Related

Excel-DNA: grouping rows via C API feature of Excel-DNA

I'm familiar with how to group a range in Excel VSTO/COM interop:
ws.EnableOutlining = true;
ws.Outline.SummaryRow = XlSummaryRow.xlSummaryAbove;
var rng = GetRangeSomeHow();
rng.EntireRow.Group();
rng.EntireRow.OutlineLevel = someLevel;
What is the most efficient way to do this in Excel-DNA? I would imagine there must be a C-API way to do it, encapsulated cleverly in Excel-DNA somehow, but for the life of me, I can't figure it out via online documentation (incl. Google).
There's a lot of posts using code similar to my sample above, but these are pretty expensive calls, especially since I need to do this ~5000 times overall (I have a really big data set).
EDIT:
So there seems to be this method call:
XlCall.Excel(XlCall.xlfGroup...)
The only problem is, I have no idea what the parameters are. It seems an ExcelReference should be passed in, but how is the .EntireRow resolved? Will the C API just handle it for me - in which case I just need to pass a new ExcelReference(1,100,1,1) and be done with it... or is there more to this?
Thanks in advance to anyone who can answer my question!
I don't think the C API GROUP function is te one you're looking for. The documentation says:
GROUP
Creates a single object from several selected objects and returns the
object identifier of the group (for example, "Group 5"). Use GROUP to
combine a number of objects so that you can move or resize them
together.
If no object is selected, only one object is selected, or a group is
already selected, GROUP returns the #VALUE! error value and interrupts
the macro.
I'd suggest you use the COM object model for this kind of thing, even in an Excel-DNA add-in. The C API has not really been updated over the years for the general sheet manipulation like this case, so you're likely to run into some features that don't work right or are incomplete relative to the COM object model.
From your Excel-DNA add-in, just make sure your get hold of the right Application root object with a call to ExcelDnaUtil.Application.
For improved performance of this kind of sheet editing, you pretty much have to use the same tricks as from VBA or VSTO - disable screen updating and calculations etc.

Microsoft Analysis - how to set dimension to show bit as True/False instead of 1/0

I'm writing a program to process a cube using Microsoft Analysis, and I want
bit values to be shown as True/False whenever I browse the cube (lets say in Excel).
I've managed to show null values as some string using 'Unknown', but I can't figure how to do the same with the actual values.
P.S. I do not want to convert it by using a CASE query in the DSV table creation. I want it to be only at the Dimension level.
Thanks.
You might "not want" to rely on a CASE statement in the DSV, but SSAS doesn't give you any other options to achieve what you want. So hold your nose and start coding...
FWIW - I prefer a SQL View (rather than calculations in a DSV) for more re-use and easier testing.

Issue with printing an arbitrary sequence of strings and images in C#

So, long story short: I'm writing a POS program, and I have a receipt printer connected and the Windows Forms printing API works great with it, much easier than I expected.
However, searching through the API, it seems that the easiest (or perhaps only) way to programmatically print something is to use the Graphics object inside the PrintPageEventArgs object in the printer's event handling method.
Every overloaded parameter list for the Graphics.DrawXXX() method requires some kind of coordinate pair to use as a reference point for where to start drawing the object passed to it.
So my question is, let's say I want to print some string value, and then an Image. Doing it the other way around (first the Image, then the string) would be easy because the reference point to start drawing the string would be (0, Image.Size.Height). However, since a string does not have a "size" associated with it, what is the best way to go about telling the printer where to start drawing an image after a string has been printed?
Let me know if this is confusing or needs additional clarification.

How can I run built-in Revit commands from C#

I am wanting to know if there is a methodology to feed calculated values to a built-in Revit command from inside a C# program, and then possibly (based on results, such as whether this makes an element too short or too long for a known "maximum span" of a particular beam) continue with my C# program and change the beam size). I am told you can invoke the Revit built-in command after execution of your c# external command, but you cannot then return to the c# program
As another example, I want to select an element to trim/extend to, and have the code figure out which "Joist" beams to extend to this element. My program would do extended filtering (such as "Reference Level", or "Workset", or "Comments", or "Mark" parameters (etc.)) and then run the built in function, providing the element to extend to and then each of my beams.
I've tried internet searches, as well as the Revit SDK samples, and nothing obviously used this (but there are a lot of csproj's to look through).
Can anyone verify that you cannot go back and forth between the C# program and the Revit built-in command?
You can programmatically invoke a built in Revit command with the UIApplication.PostCommand() method. Refer to documentation and building coder for more information. It will not execute until after the API context is over, however.
I don't think you'll be able to feed arguments into the command however, short of some kind of Win32 hack. Perhaps you will need to recreate the functionality of the built in command within the Revit API.
Unfortunately, I don't think we can do (command "_line" pnt1 pnt2) type of thing here.
Perhaps start with the SDK sample "MoveLinear". It shows how to modify end points of linear elements (which includes beams).
The main part of the sample's code is
Autodesk.Revit.DB.Line line;
//get start point via "get_EndPoint(0)"
Autodesk.Revit.DB.XYZ newStart = new XYZ(
lineLoc.Curve.GetEndPoint(0).X + 100,
lineLoc.Curve.GetEndPoint(0).Y,
lineLoc.Curve.GetEndPoint(0).Z);
//get end point via "get_EndPoint(1)"
Autodesk.Revit.DB.XYZ newEnd = new XYZ(
lineLoc.Curve.GetEndPoint(1).X,
lineLoc.Curve.GetEndPoint(1).Y + 100,
lineLoc.Curve.GetEndPoint(1).Z);
//get a new line and use it to move current element
//with property "Autodesk.Revit.DB.LocationCurve.Curve"
line = Line.CreateBound(newStart, newEnd);
lineLoc.Curve = line;
Which moves the X of the first point and the Y of the second point 100 feet.
you can try:
RevitCommandId commandId = RevitCommandId.LookupPostableCommandId(PostableCommand.PlaceAComponent);
commandData.Application.PostCommand(commandId);

How to set the start position for a video using AxShockwaveFlash (revised)

Revised question with added detail...
I'm trying to use AxShockwaveFlash to play a youtube video and start it at a specific location. This is within a C# winforms app. I have the basics. I can successfully start and stop the video. I cannot, however, figure out how to set the position and start at a specific time within the video. What property or method needs to be called to do this?
Here's what I have so far:
AxShockwaveFlashObjects.AxShockwaveFlash mFlashPlayer;
...
mFlashPlayer.Movie = #"http://www.youtube.com/v/9O9HfafzBPE?version=3&hl=ru_RU";
mFlashPlayer.Play();
I've tried setting various properties and calling various methods, but I'm just guessing. For example, I tried calling
mFlashPlayer.GotoFrame(200);
and it did nothing. Seems so simple, I'm starting to wonder if I'm encountering a bug. ?
I also tried using the standard form when using a web browser, which is to encode it directly in the url. For example, the following did not work either:
mFlashPlayer.Movie = #"http ...blah... #t=77s";
mFlashPlayer.Play();
Thanks in advance for any suggestions.
ANSWER
Apparently, I'm not authorized to post an answer, so I'm editing the question and adding it here...
Got it! The magic trick is to set the 'start' parameter in the url that you provide to the Movie property or the LoadMovie() method.
Embedded AS3 player:
http://www.youtube.com/v/VIDEO_ID?version=3&start=NUMBER_SECONDS
Chromeless AS3 player:
http://www.youtube.com/apiplayer?video_id=VIDEO_ID&version=3&start=NUMBER_SECONDS
Replace VIDEO_ID and NUMBER_SECONDS with the desired values.
Example:
mFlashPlayer.Movie = #"http://www.youtube.com/v/1ZKz2KW87Y4?version=3&start=100";
I found the required info here:
https://developers.google.com/youtube/player_parameters
That was one of the more frustrating hunts for info that I've been on in a while. Hope this post saves other folks the headaches.

Categories